mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10982 from ethereum/storage_builtin
[isoltest] Replace storage command with storage builtin.
This commit is contained in:
commit
5c02837485
@ -27,6 +27,7 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
@ -124,6 +125,12 @@ void SemanticTest::initializeBuiltins()
|
||||
{
|
||||
return util::toBigEndian(u256(0x1234));
|
||||
};
|
||||
soltestAssert(m_builtins.count("storageEmpty") == 0, "");
|
||||
m_builtins["storageEmpty"] = [this](FunctionCall const& _call) -> std::optional<bytes>
|
||||
{
|
||||
soltestAssert(_call.arguments.parameters.empty(), "No arguments expected.");
|
||||
return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0));
|
||||
};
|
||||
}
|
||||
|
||||
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
|
||||
@ -222,16 +229,7 @@ TestCase::TestResult SemanticTest::runTest(
|
||||
constructed = true;
|
||||
}
|
||||
|
||||
if (test.call().kind == FunctionCall::Kind::Storage)
|
||||
{
|
||||
test.setFailure(false);
|
||||
bytes result(1, !storageEmpty(m_contractAddress));
|
||||
test.setRawBytes(result);
|
||||
soltestAssert(test.call().expectations.rawBytes().size() == 1, "");
|
||||
if (test.call().expectations.rawBytes() != result)
|
||||
success = false;
|
||||
}
|
||||
else if (test.call().kind == FunctionCall::Kind::Constructor)
|
||||
if (test.call().kind == FunctionCall::Kind::Constructor)
|
||||
{
|
||||
if (m_transactionSuccessful == test.call().expectations.failure)
|
||||
success = false;
|
||||
@ -385,12 +383,14 @@ bool SemanticTest::checkGasCostExpectation(TestFunctionCall& io_test, bool _comp
|
||||
// or test is run with abi encoder v1 only
|
||||
// or gas used less than threshold for enforcing feature
|
||||
// or setting is "ir" and it's not included in expectations
|
||||
// or if the called function is an isoltest builtin e.g. `smokeTest` or `storageEmpty`
|
||||
if (
|
||||
!m_enforceGasCost ||
|
||||
(
|
||||
(setting == "ir" || m_gasUsed < m_enforceGasCostMinValue || m_gasUsed >= m_gas) &&
|
||||
io_test.call().expectations.gasUsed.count(setting) == 0
|
||||
)
|
||||
) ||
|
||||
io_test.call().kind == FunctionCall::Kind::Builtin
|
||||
)
|
||||
return true;
|
||||
|
||||
|
@ -41,17 +41,17 @@ contract c {
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// test_short() -> 1780731860627700044960722568376587075150542249149356309979516913770823710
|
||||
// gas legacy: 110938
|
||||
// gas legacyOptimized: 109706
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// test_long() -> 67
|
||||
// gas irOptimized: 134320
|
||||
// gas legacy: 213590
|
||||
// gas legacyOptimized: 211044
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020
|
||||
// gas legacy: 176030
|
||||
// gas legacyOptimized: 173504
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
|
@ -40,9 +40,9 @@ contract c {
|
||||
// gas irOptimized: 2470372
|
||||
// gas legacy: 2288641
|
||||
// gas legacyOptimized: 2258654
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// clear() -> 0, 0
|
||||
// gas irOptimized: 1852821
|
||||
// gas legacy: 1727169
|
||||
// gas legacyOptimized: 1698931
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -21,4 +21,4 @@ contract c {
|
||||
// setData1(uint256,uint256,uint256): 0, 0, 0 ->
|
||||
// copyStorageStorage() ->
|
||||
// getData2(uint256): 0 -> 0, 0
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -22,4 +22,4 @@ contract c {
|
||||
// gas irOptimized: 257752
|
||||
// gas legacy: 255936
|
||||
// gas legacyOptimized: 254359
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -14,10 +14,10 @@ contract c {
|
||||
// gas irOptimized: 163929
|
||||
// gas legacy: 164121
|
||||
// gas legacyOptimized: 163766
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// copy(uint256,uint256): 1, 2 -> true
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// copy(uint256,uint256): 99, 1 -> true
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// copy(uint256,uint256): 99, 2 -> true
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -43,4 +43,4 @@ contract C {
|
||||
// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000
|
||||
// gas legacy: 100595
|
||||
// h() -> 0x40, 0x60, 0x00, 0x00
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -12,6 +12,6 @@ contract c {
|
||||
// gas irOptimized: 163680
|
||||
// gas legacy: 163756
|
||||
// gas legacyOptimized: 163596
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// reset() -> true
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -7,6 +7,6 @@ contract c {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// (): 7 ->
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// del(): 7 -> true
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -14,13 +14,13 @@ contract c {
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// fill() ->
|
||||
// gas irOptimized: 535098
|
||||
// gas legacy: 504373
|
||||
// gas legacyOptimized: 499648
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// halfClear() ->
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// fullClear() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -16,11 +16,11 @@ contract c {
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// fill() -> 8
|
||||
// gas irOptimized: 168980
|
||||
// gas legacy: 165456
|
||||
// gas legacyOptimized: 164387
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -11,11 +11,11 @@ contract c {
|
||||
// compileToEwasm: also
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// fill() ->
|
||||
// gas irOptimized: 423878
|
||||
// gas legacy: 429460
|
||||
// gas legacyOptimized: 425520
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -28,4 +28,4 @@ contract c {
|
||||
// gas irOptimized: 2455497
|
||||
// gas legacy: 2416722
|
||||
// gas legacyOptimized: 2405396
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -9,4 +9,4 @@ contract c {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -23,4 +23,4 @@ contract c {
|
||||
// gas irOptimized: 527367
|
||||
// gas legacy: 454080
|
||||
// gas legacyOptimized: 443170
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -23,4 +23,4 @@ contract c {
|
||||
// gas irOptimized: 367121
|
||||
// gas legacy: 320859
|
||||
// gas legacyOptimized: 314681
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -21,4 +21,4 @@ contract c {
|
||||
// gas irOptimized: 445718
|
||||
// gas legacy: 552064
|
||||
// gas legacyOptimized: 533164
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -20,4 +20,4 @@ contract c {
|
||||
// gas irOptimized: 291114
|
||||
// gas legacy: 372763
|
||||
// gas legacyOptimized: 366846
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -14,4 +14,4 @@ contract c {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// test() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -11,8 +11,8 @@ contract c {
|
||||
// compileToEwasm: also
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// fill() ->
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// clear() ->
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -0,0 +1,6 @@
|
||||
contract StorageEmpty {
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storageEmpty -> 1
|
@ -0,0 +1,10 @@
|
||||
contract StorageNotEmpty {
|
||||
uint256 x;
|
||||
function set(uint256 _a) public { x = _a; }
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storageEmpty -> 1
|
||||
// set(uint256): 1 ->
|
||||
// storageEmpty -> 0
|
@ -6,26 +6,26 @@ contract Test {
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// set(bytes): 0x20, 3, "abc"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 0
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// set(bytes): 0x20, 31, "1234567890123456789012345678901"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 36, "12345678901234567890123456789012", "XXXX"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 3, "abc"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 0
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// set(bytes): 0x20, 3, "abc"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 36, "12345678901234567890123456789012", "XXXX"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 0
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// set(bytes): 0x20, 66, "12345678901234567890123456789012", "12345678901234567890123456789012", "12"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 3, "abc"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// set(bytes): 0x20, 0
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -23,16 +23,16 @@ contract c {
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true
|
||||
// gas irOptimized: 124227
|
||||
// gas legacy: 124736
|
||||
// gas legacyOptimized: 124179
|
||||
// test(uint256): 32 -> "3"
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// copy() -> true
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
// set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true
|
||||
// storage: nonempty
|
||||
// storageEmpty -> 0
|
||||
// del() -> true
|
||||
// storage: empty
|
||||
// storageEmpty -> 1
|
||||
|
@ -294,9 +294,8 @@ struct FunctionCall
|
||||
LowLevel,
|
||||
/// Marks a library deployment call.
|
||||
Library,
|
||||
/// Check that the storage of the current contract is empty or non-empty.
|
||||
Storage,
|
||||
/// Call to a builtin.
|
||||
/// Builtins get registered in `SemanticTest::initializeBuiltins()`.
|
||||
Builtin
|
||||
};
|
||||
Kind kind = Kind::Regular;
|
||||
|
@ -106,21 +106,6 @@ vector<solidity::frontend::test::FunctionCall> TestFileParser::parseFunctionCall
|
||||
call.kind = FunctionCall::Kind::Library;
|
||||
call.expectations.failure = false;
|
||||
}
|
||||
else if (accept(Token::Storage, true))
|
||||
{
|
||||
expect(Token::Colon);
|
||||
call.expectations.failure = false;
|
||||
call.expectations.result.push_back(Parameter());
|
||||
// empty / non-empty is encoded as false / true
|
||||
if (m_scanner.currentLiteral() == "empty")
|
||||
call.expectations.result.back().rawBytes = bytes(1, uint8_t(false));
|
||||
else if (m_scanner.currentLiteral() == "nonempty")
|
||||
call.expectations.result.back().rawBytes = bytes(1, uint8_t(true));
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(TestParserError("Expected \"empty\" or \"nonempty\"."));
|
||||
call.kind = FunctionCall::Kind::Storage;
|
||||
m_scanner.scanNextToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool lowLevelCall = false;
|
||||
|
@ -958,28 +958,6 @@ BOOST_AUTO_TEST_CASE(library)
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_storage)
|
||||
{
|
||||
char const* source = R"(
|
||||
// storage: empty
|
||||
)";
|
||||
auto const calls = parse(source);
|
||||
BOOST_REQUIRE_EQUAL(calls.size(), 1);
|
||||
BOOST_CHECK(calls.at(0).kind == FunctionCall::Kind::Storage);
|
||||
BOOST_CHECK(calls.at(0).expectations.result.front().rawBytes == bytes(1, 0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(nonempty_storage)
|
||||
{
|
||||
char const* source = R"(
|
||||
// storage: nonempty
|
||||
)";
|
||||
auto const calls = parse(source);
|
||||
BOOST_REQUIRE_EQUAL(calls.size(), 1);
|
||||
BOOST_CHECK(calls.at(0).kind == FunctionCall::Kind::Storage);
|
||||
BOOST_CHECK(calls.at(0).expectations.result.front().rawBytes == bytes(1, 1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -61,23 +61,6 @@ string TestFunctionCall::format(
|
||||
stream << _linePrefix << newline << ws << "library:" << ws << m_call.signature;
|
||||
return;
|
||||
}
|
||||
else if (m_call.kind == FunctionCall::Kind::Storage)
|
||||
{
|
||||
stream << _linePrefix << newline << ws << "storage" << colon << ws;
|
||||
soltestAssert(m_rawBytes.size() == 1, "");
|
||||
soltestAssert(m_call.expectations.rawBytes().size() == 1, "");
|
||||
bool isEmpty =
|
||||
_renderMode == RenderMode::ActualValuesExpectedGas ?
|
||||
m_rawBytes.front() == 0 :
|
||||
m_call.expectations.rawBytes().front() == 0;
|
||||
string output = isEmpty ? "empty" : "nonempty";
|
||||
if (_renderMode == RenderMode::ActualValuesExpectedGas && !matchesExpectation())
|
||||
AnsiColorized(stream, highlight, {util::formatting::RED_BACKGROUND}) << output;
|
||||
else
|
||||
stream << output;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// Formats the function signature. This is the same independent from the display-mode.
|
||||
stream << _linePrefix << newline << ws << m_call.signature;
|
||||
|
Loading…
Reference in New Issue
Block a user