mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6144 from ethereum/petersburg
Support petersburg in evmVersion
This commit is contained in:
commit
cc4598a5ed
@ -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``.
|
||||||
|
@ -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``.
|
||||||
|
@ -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)
|
||||||
|
@ -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) {}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
@ -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
|
||||||
|
@ -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.")
|
||||||
(
|
(
|
||||||
|
@ -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",
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user