Add basic support for the EVM version Paris

This mostly means testing with evmone, but instruction renaming of difficulty->prevrandao is omitted.
This commit is contained in:
Alex Beregszaszi 2022-11-09 12:12:18 +01:00 committed by Kamil Śliwak
parent 0b4b1045cf
commit eb8af2caec
13 changed files with 37 additions and 9 deletions

View File

@ -31,7 +31,7 @@ REPODIR="$(realpath "$(dirname "$0")"/..)"
# shellcheck source=scripts/common.sh # shellcheck source=scripts/common.sh
source "${REPODIR}/scripts/common.sh" source "${REPODIR}/scripts/common.sh"
EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london) EVM_VALUES=(homestead byzantium constantinople petersburg istanbul berlin london paris)
DEFAULT_EVM=london DEFAULT_EVM=london
[[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]] [[ " ${EVM_VALUES[*]} " =~ $DEFAULT_EVM ]]
OPTIMIZE_VALUES=(0 1) OPTIMIZE_VALUES=(0 1)

View File

@ -6,6 +6,7 @@ Language Features:
Compiler Features: Compiler Features:
* Commandline Interface: Return exit code ``2`` on uncaught exceptions. * Commandline Interface: Return exit code ``2`` on uncaught exceptions.
* Commandline Interface: Add `--no-cbor-metadata` that skips CBOR metadata from getting appended at the end of the bytecode. * Commandline Interface: Add `--no-cbor-metadata` that skips CBOR metadata from getting appended at the end of the bytecode.
* EVM: Basic support for the EVM version "Paris".
* Natspec: Add event Natspec inheritance for devdoc. * Natspec: Add event Natspec inheritance for devdoc.
* Standard JSON: Add a boolean field `settings.metadata.appendCBOR` that skips CBOR metadata from getting appended at the end of the bytecode. * Standard JSON: Add a boolean field `settings.metadata.appendCBOR` that skips CBOR metadata from getting appended at the end of the bytecode.
* Yul Optimizer: Allow replacing the previously hard-coded cleanup sequence by specifying custom steps after a colon delimiter (``:``) in the sequence string. * Yul Optimizer: Allow replacing the previously hard-coded cleanup sequence by specifying custom steps after a colon delimiter (``:``) in the sequence string.

View File

@ -172,7 +172,8 @@ at each version. Backward compatibility is not guaranteed between each version.
the optimizer. the optimizer.
- ``london`` (**default**) - ``london`` (**default**)
- The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly. - The block's base fee (`EIP-3198 <https://eips.ethereum.org/EIPS/eip-3198>`_ and `EIP-1559 <https://eips.ethereum.org/EIPS/eip-1559>`_) can be accessed via the global ``block.basefee`` or ``basefee()`` in inline assembly.
- ``paris``
- No changes.
.. index:: ! standard JSON, ! --standard-json .. index:: ! standard JSON, ! --standard-json
.. _compiler-api: .. _compiler-api:
@ -305,7 +306,7 @@ Input Description
}, },
// Version of the EVM to compile for. // Version of the EVM to compile for.
// Affects type checking and code generation. Can be homestead, // Affects type checking and code generation. Can be homestead,
// tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul or berlin // tangerineWhistle, spuriousDragon, byzantium, constantinople, petersburg, istanbul, berlin, london or paris
"evmVersion": "byzantium", "evmVersion": "byzantium",
// Optional: Change compilation pipeline to go through the Yul intermediate representation. // Optional: Change compilation pipeline to go through the Yul intermediate representation.
// This is false by default. // This is false by default.

View File

@ -56,10 +56,11 @@ public:
static EVMVersion istanbul() { return {Version::Istanbul}; } static EVMVersion istanbul() { return {Version::Istanbul}; }
static EVMVersion berlin() { return {Version::Berlin}; } static EVMVersion berlin() { return {Version::Berlin}; }
static EVMVersion london() { return {Version::London}; } static EVMVersion london() { return {Version::London}; }
static EVMVersion paris() { return {Version::Paris}; }
static std::optional<EVMVersion> fromString(std::string const& _version) static std::optional<EVMVersion> fromString(std::string const& _version)
{ {
for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg(), istanbul(), berlin(), london()}) for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg(), istanbul(), berlin(), london(), paris()})
if (_version == v.name()) if (_version == v.name())
return v; return v;
return std::nullopt; return std::nullopt;
@ -81,6 +82,7 @@ public:
case Version::Istanbul: return "istanbul"; case Version::Istanbul: return "istanbul";
case Version::Berlin: return "berlin"; case Version::Berlin: return "berlin";
case Version::London: return "london"; case Version::London: return "london";
case Version::Paris: return "paris";
} }
return "INVALID"; return "INVALID";
} }
@ -102,7 +104,7 @@ public:
bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); } bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); }
private: private:
enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London }; enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris };
EVMVersion(Version _version): m_version(_version) {} EVMVersion(Version _version): m_version(_version) {}

View File

@ -105,7 +105,7 @@ EVM_VERSIONS="homestead byzantium"
if [ -z "$CI" ] if [ -z "$CI" ]
then then
EVM_VERSIONS+=" constantinople petersburg istanbul berlin london" EVM_VERSIONS+=" constantinople petersburg istanbul berlin london paris"
fi fi
# And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer # And then run the Solidity unit-tests in the matrix combination of optimizer / no optimizer

View File

@ -586,7 +586,7 @@ General Information)").c_str(),
g_strEVMVersion.c_str(), g_strEVMVersion.c_str(),
po::value<string>()->value_name("version")->default_value(EVMVersion{}.name()), po::value<string>()->value_name("version")->default_value(EVMVersion{}.name()),
"Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, " "Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, "
"byzantium, constantinople, petersburg, istanbul, berlin or london." "byzantium, constantinople, petersburg, istanbul, berlin, london or paris."
) )
( (
g_strExperimentalViaIR.c_str(), g_strExperimentalViaIR.c_str(),

View File

@ -122,7 +122,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
m_evmRevision = EVMC_BERLIN; m_evmRevision = EVMC_BERLIN;
else if (_evmVersion == langutil::EVMVersion::london()) else if (_evmVersion == langutil::EVMVersion::london())
m_evmRevision = EVMC_LONDON; m_evmRevision = EVMC_LONDON;
// TODO: support EVMVersion::paris() else if (_evmVersion == langutil::EVMVersion::paris())
m_evmRevision = EVMC_PARIS;
else else
assertThrow(false, Exception, "Unsupported EVM version"); assertThrow(false, Exception, "Unsupported EVM version");

View File

@ -1082,6 +1082,8 @@ BOOST_AUTO_TEST_CASE(evm_version)
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"berlin\"") != string::npos); BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"berlin\"") != string::npos);
result = compile(inputForVersion("\"evmVersion\": \"london\",")); result = compile(inputForVersion("\"evmVersion\": \"london\","));
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"london\"") != string::npos); BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"london\"") != string::npos);
result = compile(inputForVersion("\"evmVersion\": \"paris\","));
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"paris\"") != string::npos);
// test default // test default
result = compile(inputForVersion("")); result = compile(inputForVersion(""));
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"london\"") != string::npos); BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"london\"") != string::npos);

View File

@ -5,6 +5,7 @@ contract C {
} }
// ==== // ====
// compileToEwasm: also // compileToEwasm: also
// EVMVersion: <paris
// ---- // ----
// f() -> 200000000 // f() -> 200000000
// f() -> 200000000 // f() -> 200000000

View File

@ -0,0 +1,12 @@
contract C {
function f() public returns (uint) {
return block.difficulty;
}
}
// ====
// compileToEwasm: also
// EVMVersion: >=paris
// ----
// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777
// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777
// f() -> 0xa86c2e601b6c44eb4848f7d23d9df3113fbcac42041c49cbed5000cb4f118777

View File

@ -48,7 +48,9 @@ static vector<EVMVersion> s_evmVersions = {
EVMVersion::constantinople(), EVMVersion::constantinople(),
EVMVersion::petersburg(), EVMVersion::petersburg(),
EVMVersion::istanbul(), EVMVersion::istanbul(),
EVMVersion::berlin() EVMVersion::berlin(),
EVMVersion::london(),
EVMVersion::paris()
}; };
void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, bool _quiet) void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize, bool _quiet)

View File

@ -112,6 +112,10 @@ EVMVersion ProtoConverter::evmVersionMapping(Program_Version const& _ver)
return EVMVersion::istanbul(); return EVMVersion::istanbul();
case Program::BERLIN: case Program::BERLIN:
return EVMVersion::berlin(); return EVMVersion::berlin();
case Program::LONDON:
return EVMVersion::london();
case Program::PARIS:
return EVMVersion::paris();
} }
} }

View File

@ -396,6 +396,8 @@ message Program {
PETERSBURG = 5; PETERSBURG = 5;
ISTANBUL = 6; ISTANBUL = 6;
BERLIN = 7; BERLIN = 7;
LONDON = 8;
PARIS = 9;
} }
oneof program_oneof { oneof program_oneof {
Block block = 1; Block block = 1;