Merge pull request #11335 from ethereum/builtin-init

[soltest] Improve Builtin Initialization.
This commit is contained in:
chriseth 2021-05-03 10:30:15 +02:00 committed by GitHub
commit ce0559e463
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 38 deletions

View File

@ -233,7 +233,7 @@ h160 ExecutionFramework::account(size_t _idx)
return h160(h256(u256{"0x1212121212121212121212121212120000000012"} + _idx * 0x1000), h160::AlignRight); return h160(h256(u256{"0x1212121212121212121212121212120000000012"} + _idx * 0x1000), h160::AlignRight);
} }
bool ExecutionFramework::addressHasCode(h160 const& _addr) bool ExecutionFramework::addressHasCode(h160 const& _addr) const
{ {
return m_evmcHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0; return m_evmcHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0;
} }
@ -266,12 +266,12 @@ bytes ExecutionFramework::logData(size_t _logIdx) const
return {data.begin(), data.end()}; return {data.begin(), data.end()};
} }
u256 ExecutionFramework::balanceAt(h160 const& _addr) u256 ExecutionFramework::balanceAt(h160 const& _addr) const
{ {
return u256(EVMHost::convertFromEVMC(m_evmcHost->get_balance(EVMHost::convertToEVMC(_addr)))); return u256(EVMHost::convertFromEVMC(m_evmcHost->get_balance(EVMHost::convertToEVMC(_addr))));
} }
bool ExecutionFramework::storageEmpty(h160 const& _addr) bool ExecutionFramework::storageEmpty(h160 const& _addr) const
{ {
const auto it = m_evmcHost->accounts.find(EVMHost::convertToEVMC(_addr)); const auto it = m_evmcHost->accounts.find(EVMHost::convertToEVMC(_addr));
if (it != m_evmcHost->accounts.end()) if (it != m_evmcHost->accounts.end())

View File

@ -268,9 +268,9 @@ protected:
/// @returns the (potentially newly created) _ith address. /// @returns the (potentially newly created) _ith address.
util::h160 account(size_t _i); util::h160 account(size_t _i);
u256 balanceAt(util::h160 const& _addr); u256 balanceAt(util::h160 const& _addr) const;
bool storageEmpty(util::h160 const& _addr); bool storageEmpty(util::h160 const& _addr) const;
bool addressHasCode(util::h160 const& _addr); bool addressHasCode(util::h160 const& _addr) const;
size_t numLogs() const; size_t numLogs() const;
size_t numLogTopics(size_t _logIdx) const; size_t numLogTopics(size_t _logIdx) const;

View File

@ -40,12 +40,10 @@ using namespace solidity::langutil;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::util::formatting; using namespace solidity::util::formatting;
using namespace solidity::frontend::test; using namespace solidity::frontend::test;
using namespace boost;
using namespace boost::algorithm; using namespace boost::algorithm;
using namespace boost::unit_test; using namespace boost::unit_test;
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
SemanticTest::SemanticTest( SemanticTest::SemanticTest(
string const& _filename, string const& _filename,
langutil::EVMVersion _evmVersion, langutil::EVMVersion _evmVersion,
@ -59,13 +57,12 @@ SemanticTest::SemanticTest(
EVMVersionRestrictedTestCase(_filename), EVMVersionRestrictedTestCase(_filename),
m_sources(m_reader.sources()), m_sources(m_reader.sources()),
m_lineOffset(m_reader.lineNumber()), m_lineOffset(m_reader.lineNumber()),
m_builtins(makeBuiltins()),
m_enforceViaYul(_enforceViaYul), m_enforceViaYul(_enforceViaYul),
m_enforceCompileToEwasm(_enforceCompileToEwasm), m_enforceCompileToEwasm(_enforceCompileToEwasm),
m_enforceGasCost(_enforceGasCost), m_enforceGasCost(_enforceGasCost),
m_enforceGasCostMinValue(std::move(_enforceGasCostMinValue)) m_enforceGasCostMinValue(move(_enforceGasCostMinValue))
{ {
initializeBuiltins();
static set<string> const compileViaYulAllowedValues{"also", "true", "false", "default"}; static set<string> const compileViaYulAllowedValues{"also", "true", "false", "default"};
static set<string> const yulRunTriggers{"also", "true"}; static set<string> const yulRunTriggers{"also", "true"};
static set<string> const legacyRunTriggers{"also", "false", "default"}; static set<string> const legacyRunTriggers{"also", "false", "default"};
@ -118,29 +115,37 @@ SemanticTest::SemanticTest(
} }
} }
void SemanticTest::initializeBuiltins() map<string, Builtin> SemanticTest::makeBuiltins() const
{ {
solAssert(m_builtins.count("smokeTest") == 0, ""); return {
m_builtins["smokeTest"] = [](FunctionCall const&) -> std::optional<bytes> {
{ "smokeTest",
return util::toBigEndian(u256(0x1234)); [](FunctionCall const&) -> optional<bytes>
}; {
soltestAssert(m_builtins.count("balance") == 0, ""); return util::toBigEndian(u256(0x1234));
m_builtins["balance"] = [this](FunctionCall const& _call) -> std::optional<bytes> }
{ },
soltestAssert(_call.arguments.parameters.size() <= 1, "Account address expected."); {
h160 address; "balance",
if (_call.arguments.parameters.size() == 1) [this](FunctionCall const& _call) -> optional<bytes>
address = h160(_call.arguments.parameters.at(0).rawString); {
else soltestAssert(_call.arguments.parameters.size() <= 1, "Account address expected.");
address = m_contractAddress; h160 address;
return util::toBigEndian(SolidityExecutionFramework::balanceAt(address)); if (_call.arguments.parameters.size() == 1)
}; address = h160(_call.arguments.parameters.at(0).rawString);
soltestAssert(m_builtins.count("storageEmpty") == 0, ""); else
m_builtins["storageEmpty"] = [this](FunctionCall const& _call) -> std::optional<bytes> address = m_contractAddress;
{ return util::toBigEndian(balanceAt(address));
soltestAssert(_call.arguments.parameters.empty(), "No arguments expected."); }
return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0)); },
{
"storageEmpty",
[this](FunctionCall const& _call) -> optional<bytes>
{
soltestAssert(_call.arguments.parameters.empty(), "No arguments expected.");
return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0));
}
}
}; };
} }
@ -257,7 +262,7 @@ TestCase::TestResult SemanticTest::runTest(
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value); output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
else if (test.call().kind == FunctionCall::Kind::Builtin) else if (test.call().kind == FunctionCall::Kind::Builtin)
{ {
std::optional<bytes> builtinOutput = m_builtins.at(test.call().signature)(test.call()); optional<bytes> builtinOutput = m_builtins.at(test.call().signature)(test.call());
if (builtinOutput.has_value()) if (builtinOutput.has_value())
{ {
m_transactionSuccessful = true; m_transactionSuccessful = true;
@ -296,7 +301,7 @@ TestCase::TestResult SemanticTest::runTest(
success = false; success = false;
test.setFailure(!m_transactionSuccessful); test.setFailure(!m_transactionSuccessful);
test.setRawBytes(std::move(output)); test.setRawBytes(move(output));
test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName(m_sources.mainSourceFile))); test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName(m_sources.mainSourceFile)));
} }
} }

View File

@ -80,10 +80,11 @@ public:
private: private:
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun); TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun);
bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const; bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;
void initializeBuiltins(); std::map<std::string, Builtin> makeBuiltins() const;
SourceMap m_sources; SourceMap m_sources;
std::size_t m_lineOffset; std::size_t m_lineOffset;
std::vector<TestFunctionCall> m_tests; std::vector<TestFunctionCall> m_tests;
std::map<std::string, Builtin> const m_builtins;
bool m_testCaseWantsYulRun = false; bool m_testCaseWantsYulRun = false;
bool m_testCaseWantsEwasmRun = false; bool m_testCaseWantsEwasmRun = false;
bool m_testCaseWantsLegacyRun = true; bool m_testCaseWantsLegacyRun = true;
@ -93,8 +94,6 @@ private:
bool m_allowNonExistingFunctions = false; bool m_allowNonExistingFunctions = false;
bool m_canEnableYulRun = false; bool m_canEnableYulRun = false;
bool m_canEnableEwasmRun = false; bool m_canEnableEwasmRun = false;
std::map<std::string, Builtin> m_builtins{};
bool m_gasCostFailure = false; bool m_gasCostFailure = false;
bool m_enforceGasCost = false; bool m_enforceGasCost = false;
u256 m_enforceGasCostMinValue; u256 m_enforceGasCostMinValue;