diff --git a/docs/compiling-a-contract.rst b/docs/compiling-a-contract.rst index 83571203e8..fdcb8b7271 100644 --- a/docs/compiling-a-contract.rst +++ b/docs/compiling-a-contract.rst @@ -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, the compiler team maintains an informal policy 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 @@ -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). diff --git a/tests/functional/syntax/test_self_balance.py b/tests/functional/syntax/test_self_balance.py index d22d8a2750..28cbd05453 100644 --- a/tests/functional/syntax/test_self_balance.py +++ b/tests/functional/syntax/test_self_balance.py @@ -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}) diff --git a/tests/unit/cli/vyper_json/test_get_settings.py b/tests/unit/cli/vyper_json/test_get_settings.py index 989d4565cd..975cb9d143 100644 --- a/tests/unit/cli/vyper_json/test_get_settings.py +++ b/tests/unit/cli/vyper_json/test_get_settings.py @@ -18,6 +18,8 @@ def test_unknown_evm(): "byzantium", "constantinople", "petersburg", + "istanbul", + "berlin", ], ) def test_early_evm(evm_version): @@ -25,6 +27,6 @@ def test_early_evm(evm_version): 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}}) diff --git a/tests/unit/compiler/test_opcodes.py b/tests/unit/compiler/test_opcodes.py index ed64f343c4..710348a274 100644 --- a/tests/unit/compiler/test_opcodes.py +++ b/tests/unit/compiler/test_opcodes.py @@ -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): @@ -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 diff --git a/tests/unit/compiler/test_pre_parser.py b/tests/unit/compiler/test_pre_parser.py index 02076ed07e..128b6b16eb 100644 --- a/tests/unit/compiler/test_pre_parser.py +++ b/tests/unit/compiler/test_pre_parser.py @@ -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): diff --git a/vyper/cli/vyper_json.py b/vyper/cli/vyper_json.py index 21073cabeb..1f914e2dc9 100755 --- a/vyper/cli/vyper_json.py +++ b/vyper/cli/vyper_json.py @@ -144,8 +144,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}'") diff --git a/vyper/codegen/expr.py b/vyper/codegen/expr.py index 7c39a4f5cf..d7afe6c7f6 100644 --- a/vyper/codegen/expr.py +++ b/vyper/codegen/expr.py @@ -31,7 +31,6 @@ from vyper.exceptions import ( CodegenPanic, CompilerPanic, - EvmVersionException, StructureException, TypeCheckFailure, TypeMismatch, @@ -222,11 +221,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] @@ -302,10 +297,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 diff --git a/vyper/codegen/function_definitions/common.py b/vyper/codegen/function_definitions/common.py index d017ba7b81..a130f41565 100644 --- a/vyper/codegen/function_definitions/common.py +++ b/vyper/codegen/function_definitions/common.py @@ -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]]] diff --git a/vyper/evm/opcodes.py b/vyper/evm/opcodes.py index 767d634c89..48edf48f19 100644 --- a/vyper/evm/opcodes.py +++ b/vyper/evm/opcodes.py @@ -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)) @@ -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), @@ -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), @@ -76,12 +76,12 @@ "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), @@ -89,7 +89,7 @@ "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), @@ -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 = {