Merge pull request from ethereum/petersburg

Support petersburg in evmVersion
This commit is contained in:
Alex Beregszaszi 2019-03-04 13:50:50 +00:00 committed by GitHub
commit cc4598a5ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 28 additions and 19 deletions

View File

@ -6,6 +6,7 @@ Language Features:
Compiler Features: Compiler Features:
* Support ``petersburg`` as ``evmVersion``.
* Inline Assembly: Consider ``extcodehash`` as part of Constantinople. * Inline Assembly: Consider ``extcodehash`` as part of Constantinople.
* Inline Assembly: Instructions unavailable to the currently configured EVM are errors now. * Inline Assembly: Instructions unavailable to the currently configured EVM are errors now.
* SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``. * SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``.

View File

@ -162,7 +162,6 @@ Note that the order of arguments can be seen to be reversed in non-functional st
Opcodes marked with ``-`` do not push an item onto the stack (do not return a result), Opcodes marked with ``-`` do not push an item onto the stack (do not return a result),
those marked with ``*`` are special and all others push exactly one item onto the stack (their "return value"). those marked with ``*`` are special and all others push exactly one item onto the stack (their "return value").
Opcodes marked with ``F``, ``H``, ``B`` or ``C`` are present since Frontier, Homestead, Byzantium or Constantinople, respectively. Opcodes marked with ``F``, ``H``, ``B`` or ``C`` are present since Frontier, Homestead, Byzantium or Constantinople, respectively.
Constantinople is still in planning and all instructions marked as such will result in an invalid instruction exception.
In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to 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 position ``p``. but not including position ``b`` and ``storage[p]`` signifies the storage contents at position ``p``.

View File

@ -108,18 +108,21 @@ at each version. Backward compatibility is not guaranteed between each version.
- ``homestead`` (oldest version) - ``homestead`` (oldest version)
- ``tangerineWhistle`` - ``tangerineWhistle``
- gas cost for access to other accounts increased, relevant for gas estimation and the optimizer. - Gas cost for access to other accounts increased, relevant for gas estimation and the optimizer.
- all gas sent by default for external calls, previously a certain amount had to be retained. - All gas sent by default for external calls, previously a certain amount had to be retained.
- ``spuriousDragon`` - ``spuriousDragon``
- gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer. - Gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer.
- ``byzantium`` (**default**) - ``byzantium`` (**default**)
- opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly. - Opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly.
- the ``staticcall`` opcode is used when calling non-library view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions. - The ``staticcall`` opcode is used when calling non-library view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions.
- it is possible to access dynamic data returned from function calls. - It is possible to access dynamic data returned from function calls.
- ``revert`` opcode introduced, which means that ``revert()`` will not waste gas. - ``revert`` opcode introduced, which means that ``revert()`` will not waste gas.
- ``constantinople`` (still in progress) - ``constantinople``
- opcodes ``shl``, ``shr`` and ``sar`` are available in assembly. - Opcodes ``create2`, ``extcodehash``, ``shl``, ``shr`` and ``sar`` are available in assembly.
- shifting operators use shifting opcodes and thus need less gas. - Shifting operators use shifting opcodes and thus need less gas.
- ``petersburg``
- The compiler behaves the same way as with constantinople.
.. _compiler-api: .. _compiler-api:
@ -217,7 +220,7 @@ Input Description
"yulDetails": {} "yulDetails": {}
} }
}, },
"evmVersion": "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium or constantinople "evmVersion": "byzantium", // Version of the EVM to compile for. Affects type checking and code generation. Can be homestead, tangerineWhistle, spuriousDragon, byzantium, constantinople or petersburg
// Metadata settings (optional) // Metadata settings (optional)
"metadata": { "metadata": {
// Use only literal content and not URLs (false by default) // Use only literal content and not URLs (false by default)

View File

@ -30,7 +30,7 @@ namespace langutil
/** /**
* A version specifier of the EVM we want to compile to. * A version specifier of the EVM we want to compile to.
* Defaults to the latest version. * Defaults to the latest version deployed on Ethereum mainnet at the time of compiler release.
*/ */
class EVMVersion: class EVMVersion:
boost::less_than_comparable<EVMVersion>, boost::less_than_comparable<EVMVersion>,
@ -44,10 +44,11 @@ public:
static EVMVersion spuriousDragon() { return {Version::SpuriousDragon}; } static EVMVersion spuriousDragon() { return {Version::SpuriousDragon}; }
static EVMVersion byzantium() { return {Version::Byzantium}; } static EVMVersion byzantium() { return {Version::Byzantium}; }
static EVMVersion constantinople() { return {Version::Constantinople}; } static EVMVersion constantinople() { return {Version::Constantinople}; }
static EVMVersion petersburg() { return {Version::Petersburg}; }
static boost::optional<EVMVersion> fromString(std::string const& _version) static boost::optional<EVMVersion> fromString(std::string const& _version)
{ {
for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople()}) for (auto const& v: {homestead(), tangerineWhistle(), spuriousDragon(), byzantium(), constantinople(), petersburg()})
if (_version == v.name()) if (_version == v.name())
return v; return v;
return {}; return {};
@ -65,6 +66,7 @@ public:
case Version::SpuriousDragon: return "spuriousDragon"; case Version::SpuriousDragon: return "spuriousDragon";
case Version::Byzantium: return "byzantium"; case Version::Byzantium: return "byzantium";
case Version::Constantinople: return "constantinople"; case Version::Constantinople: return "constantinople";
case Version::Petersburg: return "petersburg";
} }
return "INVALID"; return "INVALID";
} }
@ -81,7 +83,7 @@ public:
bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); } bool canOverchargeGasForCall() const { return *this >= tangerineWhistle(); }
private: private:
enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople }; enum class Version { Homestead, TangerineWhistle, SpuriousDragon, Byzantium, Constantinople, Petersburg };
EVMVersion(Version _version): m_version(_version) {} EVMVersion(Version _version): m_version(_version) {}

View File

@ -325,7 +325,7 @@ bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
analysisInfo, analysisInfo,
errorsIgnored, errorsIgnored,
errorTypeForLoose, errorTypeForLoose,
yul::EVMDialect::looseAssemblyForEVM(EVMVersion::constantinople()), yul::EVMDialect::looseAssemblyForEVM(EVMVersion::petersburg()),
resolver resolver
).analyze(_inlineAssembly.operations()); ).analyze(_inlineAssembly.operations());
return false; return false;

View File

@ -1042,7 +1042,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
} }
// Using latest EVM Version for now, it will be run again later. // Using latest EVM Version for now, it will be run again later.
yul::Parser asmParser(m_errorReporter, yul::EVMDialect::looseAssemblyForEVM(EVMVersion::constantinople())); yul::Parser asmParser(m_errorReporter, yul::EVMDialect::looseAssemblyForEVM(EVMVersion::petersburg()));
shared_ptr<yul::Block> block = asmParser.parse(m_scanner, true); shared_ptr<yul::Block> block = asmParser.parse(m_scanner, true);
if (block == nullptr) if (block == nullptr)
BOOST_THROW_EXCEPTION(FatalError()); BOOST_THROW_EXCEPTION(FatalError());

View File

@ -181,7 +181,7 @@ EVM_VERSIONS="homestead byzantium"
if [ "$CIRCLECI" ] || [ -z "$CI" ] if [ "$CIRCLECI" ] || [ -z "$CI" ]
then then
EVM_VERSIONS+=" constantinople" EVM_VERSIONS+=" constantinople petersburg"
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

@ -607,7 +607,7 @@ Allowed options)",
( (
g_strEVMVersion.c_str(), g_strEVMVersion.c_str(),
po::value<string>()->value_name("version"), po::value<string>()->value_name("version"),
"Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, byzantium (default) or constantinople." "Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, byzantium (default), constantinople or petersburg."
) )
(g_argOptimize.c_str(), "Enable bytecode optimizer.") (g_argOptimize.c_str(), "Enable bytecode optimizer.")
( (

View File

@ -248,6 +248,8 @@ void RPCSession::test_setChainParams(vector<string> const& _accounts)
} }
if (test::Options::get().evmVersion() >= langutil::EVMVersion::constantinople()) if (test::Options::get().evmVersion() >= langutil::EVMVersion::constantinople())
forks += "\"constantinopleForkBlock\": \"0x00\",\n"; forks += "\"constantinopleForkBlock\": \"0x00\",\n";
if (test::Options::get().evmVersion() >= langutil::EVMVersion::petersburg())
forks += "\"constantinopleFixForkBlock\": \"0x00\",\n";
static string const c_configString = R"( static string const c_configString = R"(
{ {
"sealEngine": "NoProof", "sealEngine": "NoProof",

View File

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

View File

@ -206,7 +206,7 @@ public:
private: private:
ErrorList m_errors; ErrorList m_errors;
shared_ptr<yul::Block> m_ast; shared_ptr<yul::Block> m_ast;
shared_ptr<Dialect> m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion::constantinople())}; shared_ptr<Dialect> m_dialect{EVMDialect::strictAssemblyForEVMObjects(EVMVersion::petersburg())};
shared_ptr<AsmAnalysisInfo> m_analysisInfo; shared_ptr<AsmAnalysisInfo> m_analysisInfo;
shared_ptr<NameDispenser> m_nameDispenser; shared_ptr<NameDispenser> m_nameDispenser;
}; };