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

feat: drop istanbul and berlin support #3843

Merged
merged 9 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
16 changes: 3 additions & 13 deletions docs/compiling-a-contract.rst
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,10 @@ When using the JSON interface, you can include the ``"evmVersion"`` key within t
Target Options
--------------

The following is a list of supported EVM versions, and changes in the compiler introduced with each version. Backward compatibility is not guaranteed between each version.
The following is a list of supported EVM versions, and changes in the compiler introduced with each version. Backward compatibility is not guaranteed between each version. In general, there is a soft rule that the compiler will support 3 years of hard fork rulesets, but this policy may be revisited as appropriate.


.. py:attribute:: istanbul

- The ``CHAINID`` opcode is accessible via ``chain.id``
- The ``SELFBALANCE`` opcode is used for calls to ``self.balance``
- Gas estimates changed for ``SLOAD`` and ``BALANCE``

.. py:attribute:: berlin

- Gas estimates changed for ``EXTCODESIZE``, ``EXTCODECOPY``, ``EXTCODEHASH``, ``SLOAD``, ``SSTORE``, ``CALL``, ``CALLCODE``, ``DELEGATECALL`` and ``STATICCALL``
- Functions marked with ``@nonreentrant`` are protected with different values (3 and 2) than contracts targeting pre-berlin.
- ``BASEFEE`` is accessible via ``block.basefee``
.. py:attribute:: london

.. py:attribute:: paris

Expand Down Expand Up @@ -247,7 +237,7 @@ The following example describes the expected input format of ``vyper-json``. Com
},
// Optional
"settings": {
"evmVersion": "shanghai", // EVM version to compile for. Can be istanbul, berlin, paris, shanghai (default) or cancun (experimental!).
"evmVersion": "shanghai", // EVM version to compile for. Can be london, paris, shanghai (default) or cancun (experimental!).
// optional, optimization mode
// defaults to "gas". can be one of "gas", "codesize", "none",
// false and true (the last two are for backwards compatibility).
Expand Down
5 changes: 1 addition & 4 deletions tests/functional/syntax/test_self_balance.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ def __default__():
"""
settings = Settings(evm_version=evm_version)
opcodes = compiler.compile_code(code, output_formats=["opcodes"], settings=settings)["opcodes"]
if EVM_VERSIONS[evm_version] >= EVM_VERSIONS["istanbul"]:
assert "SELFBALANCE" in opcodes
else:
assert "SELFBALANCE" not in opcodes
assert "SELFBALANCE" in opcodes

c = get_contract_with_gas_estimation(code, evm_version=evm_version)
w3.eth.send_transaction({"to": c.address, "value": 1337})
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/cli/vyper_json/test_get_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ def test_unknown_evm():
"byzantium",
"constantinople",
"petersburg",
"istanbul",
"berlin",
],
)
def test_early_evm(evm_version):
with pytest.raises(JSONError):
get_evm_version({"settings": {"evmVersion": evm_version}})


@pytest.mark.parametrize("evm_version", ["istanbul", "berlin", "paris", "shanghai", "cancun"])
@pytest.mark.parametrize("evm_version", ["london", "paris", "shanghai", "cancun"])
def test_valid_evm(evm_version):
assert evm_version == get_evm_version({"settings": {"evmVersion": evm_version}})
14 changes: 5 additions & 9 deletions tests/unit/compiler/test_opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ def test_version_check(evm_version):
assert opcodes.version_check(begin=evm_version)
assert opcodes.version_check(end=evm_version)
assert opcodes.version_check(begin=evm_version, end=evm_version)
if evm_version not in ("istanbul"):
assert not opcodes.version_check(end="istanbul")
istanbul_check = opcodes.version_check(begin="istanbul")
assert istanbul_check == (opcodes.EVM_VERSIONS[evm_version] >= opcodes.EVM_VERSIONS["istanbul"])
if evm_version not in ("london",):
assert not opcodes.version_check(end="london")
london_check = opcodes.version_check(begin="london")
assert london_check == (opcodes.EVM_VERSIONS[evm_version] >= opcodes.EVM_VERSIONS["london"])


def test_get_opcodes(evm_version):
Expand All @@ -50,11 +50,7 @@ def test_get_opcodes(evm_version):
assert "CHAINID" in ops
assert ops["CREATE2"][-1] == 32000

if evm_version in ("london", "berlin", "paris", "shanghai", "cancun"):
assert ops["SLOAD"][-1] == 2100
else:
assert evm_version == "istanbul"
assert ops["SLOAD"][-1] == 800
assert ops["SLOAD"][-1] == 2100

if evm_version in ("shanghai", "cancun"):
assert "PUSH0" in ops
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/compiler/test_pre_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ def test():

def test_evm_version_check(assert_compile_failed):
code = """
#pragma evm-version berlin
#pragma evm-version london
"""
assert compile_code(code, settings=Settings(evm_version=None)) is not None
assert compile_code(code, settings=Settings(evm_version="berlin")) is not None
assert compile_code(code, settings=Settings(evm_version="london")) is not None
# should fail if compile options indicate different evm version
# from source pragma
with pytest.raises(StructureException):
Expand Down
4 changes: 3 additions & 1 deletion vyper/cli/vyper_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,10 @@ def get_evm_version(input_dict: dict) -> Optional[str]:
"spuriousDragon",
"byzantium",
"constantinople",
"istanbul",
"berlin",
):
raise JSONError("Vyper does not support pre-istanbul EVM versions")
raise JSONError("Vyper does not support pre-london EVM versions")
if evm_version not in EVM_VERSIONS:
raise JSONError(f"Unknown EVM version - '{evm_version}'")

Expand Down
11 changes: 1 addition & 10 deletions vyper/codegen/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
from vyper.exceptions import (
CodegenPanic,
CompilerPanic,
EvmVersionException,
StructureException,
TypeCheckFailure,
TypeMismatch,
Expand Down Expand Up @@ -230,11 +229,7 @@ def parse_Attribute(self):
if self.expr.attr == "balance":
addr = Expr.parse_value_expr(self.expr.value, self.context)
if addr.typ == AddressT():
if (
isinstance(self.expr.value, vy_ast.Name)
and self.expr.value.id == "self"
and version_check(begin="istanbul")
):
if isinstance(self.expr.value, vy_ast.Name) and self.expr.value.id == "self":
seq = ["selfbalance"]
else:
seq = ["balance", addr]
Expand Down Expand Up @@ -310,10 +305,6 @@ def parse_Attribute(self):
elif key == "tx.gasprice":
return IRnode.from_list(["gasprice"], typ=UINT256_T)
elif key == "chain.id":
if not version_check(begin="istanbul"):
raise EvmVersionException(
"chain.id is unavailable prior to istanbul ruleset", self.expr
)
return IRnode.from_list(["chainid"], typ=UINT256_T)

# Other variables
Expand Down
10 changes: 5 additions & 5 deletions vyper/codegen/function_definitions/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,14 @@ def get_nonreentrant_lock(func_t):
LOAD, STORE = "sload", "sstore"
if version_check(begin="cancun"):
LOAD, STORE = "tload", "tstore"

if version_check(begin="berlin"):
# any nonzero values would work here (see pricing as of net gas
# for tload/tstore we don't need to care about net gas metering,
# choose small constants (e.g. 0 can be replaced by PUSH0)
final_value, temp_value = 0, 1
else:
# any nonzero values can work here (see pricing as of net gas
# metering); these values are chosen so that downgrading to the
# 0,1 scheme (if it is somehow necessary) is safe.
final_value, temp_value = 3, 2
else:
final_value, temp_value = 0, 1

check_notset = ["assert", ["ne", temp_value, [LOAD, nkey]]]

Expand Down
30 changes: 15 additions & 15 deletions vyper/evm/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
# 1. Fork rules go from oldest (lowest value) to newest (highest value).
# 2. Fork versions aren't actually tied to anything. They are not a part of our
# official API. *DO NOT USE THE VALUES FOR ANYTHING IMPORTANT* besides versioning.
# 3. Per VIP-3365, we support mainnet fork choice rules up to 1 year old
# 3. Per VIP-3365, we support mainnet fork choice rules up to 3 years old
# (and may optionally have forward support for experimental/unreleased
# fork choice rules)
_evm_versions = ("istanbul", "berlin", "london", "paris", "shanghai", "cancun")
_evm_versions = ("london", "paris", "shanghai", "cancun")
EVM_VERSIONS: dict[str, int] = dict((v, i) for i, v in enumerate(_evm_versions))


Expand All @@ -22,7 +22,7 @@
# opcode as hex value
# number of values removed from stack
# number of values added to stack
# gas cost (istanbul, berlin, paris, shanghai, cancun)
# gas cost (london, paris, shanghai, cancun)
OPCODES: OpcodeMap = {
"STOP": (0x00, 0, 0, 0),
"ADD": (0x01, 2, 1, 3),
Expand Down Expand Up @@ -62,11 +62,11 @@
"CODESIZE": (0x38, 0, 1, 2),
"CODECOPY": (0x39, 3, 0, 3),
"GASPRICE": (0x3A, 0, 1, 2),
"EXTCODESIZE": (0x3B, 1, 1, (700, 2600)),
"EXTCODECOPY": (0x3C, 4, 0, (700, 2600)),
"EXTCODESIZE": (0x3B, 1, 1, 2600),
"EXTCODECOPY": (0x3C, 4, 0, 2600),
"RETURNDATASIZE": (0x3D, 0, 1, 2),
"RETURNDATACOPY": (0x3E, 3, 0, 3),
"EXTCODEHASH": (0x3F, 1, 1, (700, 2600)),
"EXTCODEHASH": (0x3F, 1, 1, 2600),
"BLOCKHASH": (0x40, 1, 1, 20),
"COINBASE": (0x41, 0, 1, 2),
"TIMESTAMP": (0x42, 0, 1, 2),
Expand All @@ -76,20 +76,20 @@
"GASLIMIT": (0x45, 0, 1, 2),
"CHAINID": (0x46, 0, 1, 2),
"SELFBALANCE": (0x47, 0, 1, 5),
"BASEFEE": (0x48, 0, 1, (None, 2)),
"BASEFEE": (0x48, 0, 1, 2),
"POP": (0x50, 1, 0, 2),
"MLOAD": (0x51, 1, 1, 3),
"MSTORE": (0x52, 2, 0, 3),
"MSTORE8": (0x53, 2, 0, 3),
"SLOAD": (0x54, 1, 1, (800, 2100)),
"SLOAD": (0x54, 1, 1, 2100),
"SSTORE": (0x55, 2, 0, 20000),
"JUMP": (0x56, 1, 0, 8),
"JUMPI": (0x57, 2, 0, 10),
"PC": (0x58, 0, 1, 2),
"MSIZE": (0x59, 0, 1, 2),
"GAS": (0x5A, 0, 1, 2),
"JUMPDEST": (0x5B, 0, 0, 1),
"MCOPY": (0x5E, 3, 0, (None, None, None, None, None, 3)),
"MCOPY": (0x5E, 3, 0, (None, None, None, 3)),
"PUSH0": (0x5F, 0, 1, 2),
"PUSH1": (0x60, 0, 1, 3),
"PUSH2": (0x61, 0, 1, 3),
Expand Down Expand Up @@ -161,19 +161,19 @@
"LOG3": (0xA3, 5, 0, 1500),
"LOG4": (0xA4, 6, 0, 1875),
"CREATE": (0xF0, 3, 1, 32000),
"CALL": (0xF1, 7, 1, (700, 2100)),
"CALLCODE": (0xF2, 7, 1, (700, 2100)),
"CALL": (0xF1, 7, 1, 2100),
"CALLCODE": (0xF2, 7, 1, 2100),
"RETURN": (0xF3, 2, 0, 0),
"DELEGATECALL": (0xF4, 6, 1, (700, 2100)),
"DELEGATECALL": (0xF4, 6, 1, 2100),
"CREATE2": (0xF5, 4, 1, 32000),
"SELFDESTRUCT": (0xFF, 1, 0, 25000),
"STATICCALL": (0xFA, 6, 1, (700, 2100)),
"STATICCALL": (0xFA, 6, 1, 2100),
"REVERT": (0xFD, 2, 0, 0),
"INVALID": (0xFE, 0, 0, 0),
"DEBUG": (0xA5, 1, 0, 0),
"BREAKPOINT": (0xA6, 0, 0, 0),
"TLOAD": (0x5C, 1, 1, (None, None, None, None, None, 100)),
"TSTORE": (0x5D, 2, 0, (None, None, None, None, None, 100)),
"TLOAD": (0x5C, 1, 1, (None, None, None, 100)),
"TSTORE": (0x5D, 2, 0, (None, None, None, 100)),
}

PSEUDO_OPCODES: OpcodeMap = {
Expand Down
Loading