mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
@@ -20,13 +20,15 @@
|
||||
* Framework for executing contracts and testing them using RPC.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <libdevcore/CommonIO.h>
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <libdevcore/CommonIO.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::test;
|
||||
@@ -49,6 +51,7 @@ string getIPCSocketPath()
|
||||
|
||||
ExecutionFramework::ExecutionFramework() :
|
||||
m_rpc(RPCSession::instance(getIPCSocketPath())),
|
||||
m_evmVersion(dev::test::Options::get().evmVersion()),
|
||||
m_optimize(dev::test::Options::get().optimize),
|
||||
m_showMessages(dev::test::Options::get().showMessages),
|
||||
m_sender(m_rpc.account(0))
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <test/TestHelper.h>
|
||||
#include <test/RPCSession.h>
|
||||
|
||||
#include <libsolidity/interface/EVMVersion.h>
|
||||
|
||||
#include <libdevcore/FixedHash.h>
|
||||
#include <libdevcore/SHA3.h>
|
||||
|
||||
@@ -227,6 +229,7 @@ protected:
|
||||
bytes data;
|
||||
};
|
||||
|
||||
solidity::EVMVersion m_evmVersion;
|
||||
unsigned m_optimizeRuns = 200;
|
||||
bool m_optimize = false;
|
||||
bool m_showMessages = false;
|
||||
|
||||
+2
-1
@@ -60,7 +60,8 @@ bool isValidMetadata(string const& _metadata)
|
||||
!metadata.isMember("compiler") ||
|
||||
!metadata.isMember("settings") ||
|
||||
!metadata.isMember("sources") ||
|
||||
!metadata.isMember("output")
|
||||
!metadata.isMember("output") ||
|
||||
!metadata["settings"].isMember("evmVersion")
|
||||
)
|
||||
return false;
|
||||
|
||||
|
||||
+14
-4
@@ -19,7 +19,11 @@
|
||||
/// @file RPCSession.cpp
|
||||
/// Low-level IPC communication between the test framework and the Ethereum node.
|
||||
|
||||
#include "RPCSession.h"
|
||||
#include <test/RPCSession.h>
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/interface/EVMVersion.h>
|
||||
|
||||
#include <libdevcore/CommonData.h>
|
||||
|
||||
@@ -215,6 +219,13 @@ string RPCSession::personal_newAccount(string const& _password)
|
||||
|
||||
void RPCSession::test_setChainParams(vector<string> const& _accounts)
|
||||
{
|
||||
string forks;
|
||||
if (test::Options::get().evmVersion() >= solidity::EVMVersion::tangerineWhistle())
|
||||
forks += "\"EIP150ForkBlock\": \"0x00\",\n";
|
||||
if (test::Options::get().evmVersion() >= solidity::EVMVersion::spuriousDragon())
|
||||
forks += "\"EIP158ForkBlock\": \"0x00\",\n";
|
||||
if (test::Options::get().evmVersion() >= solidity::EVMVersion::byzantium())
|
||||
forks += "\"byzantiumForkBlock\": \"0x00\",\n";
|
||||
static string const c_configString = R"(
|
||||
{
|
||||
"sealEngine": "NoProof",
|
||||
@@ -223,9 +234,8 @@ void RPCSession::test_setChainParams(vector<string> const& _accounts)
|
||||
"maximumExtraDataSize": "0x1000000",
|
||||
"blockReward": "0x",
|
||||
"allowFutureBlocks": true,
|
||||
"homesteadForkBlock": "0x00",
|
||||
"EIP150ForkBlock": "0x00",
|
||||
"EIP158ForkBlock": "0x00"
|
||||
)" + forks + R"(
|
||||
"homesteadForkBlock": "0x00"
|
||||
},
|
||||
"genesis": {
|
||||
"author": "0000000000000010000000000000000000000000",
|
||||
|
||||
+24
-1
@@ -19,8 +19,12 @@
|
||||
* @date 2014
|
||||
*/
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/interface/EVMVersion.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
#include "TestHelper.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::test;
|
||||
|
||||
@@ -41,6 +45,11 @@ Options::Options()
|
||||
}
|
||||
else if (string(suite.argv[i]) == "--optimize")
|
||||
optimize = true;
|
||||
else if (string(suite.argv[i]) == "--evm-version")
|
||||
{
|
||||
evmVersionString = i + 1 < suite.argc ? suite.argv[i + 1] : "INVALID";
|
||||
++i;
|
||||
}
|
||||
else if (string(suite.argv[i]) == "--show-messages")
|
||||
showMessages = true;
|
||||
else if (string(suite.argv[i]) == "--no-ipc")
|
||||
@@ -52,3 +61,17 @@ Options::Options()
|
||||
if (auto path = getenv("ETH_TEST_IPC"))
|
||||
ipcPath = path;
|
||||
}
|
||||
|
||||
dev::solidity::EVMVersion Options::evmVersion() const
|
||||
{
|
||||
if (!evmVersionString.empty())
|
||||
{
|
||||
// We do this check as opposed to in the constructor because the BOOST_REQUIRE
|
||||
// macros cannot yet be used in the constructor.
|
||||
auto version = solidity::EVMVersion::fromString(evmVersionString);
|
||||
BOOST_REQUIRE_MESSAGE(version, "Invalid EVM version: " + evmVersionString);
|
||||
return *version;
|
||||
}
|
||||
else
|
||||
return dev::solidity::EVMVersion();
|
||||
}
|
||||
|
||||
+8
-1
@@ -19,11 +19,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <libsolidity/interface/EVMVersion.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace test
|
||||
@@ -37,9 +40,13 @@ struct Options: boost::noncopyable
|
||||
bool disableIPC = false;
|
||||
bool disableSMT = false;
|
||||
|
||||
solidity::EVMVersion evmVersion() const;
|
||||
|
||||
static Options const& get();
|
||||
|
||||
private:
|
||||
std::string evmVersionString;
|
||||
|
||||
Options();
|
||||
};
|
||||
|
||||
|
||||
@@ -345,7 +345,7 @@ protected:
|
||||
if (!s_compiledEns)
|
||||
{
|
||||
vector<string> errors;
|
||||
s_compiledEns.reset(new bytes(compileLLL(ensCode, dev::test::Options::get().optimize, &errors)));
|
||||
s_compiledEns.reset(new bytes(compileLLL(ensCode, dev::test::Options::get().evmVersion(), dev::test::Options::get().optimize, &errors)));
|
||||
BOOST_REQUIRE(errors.empty());
|
||||
}
|
||||
sendMessage(*s_compiledEns, true);
|
||||
|
||||
@@ -396,7 +396,7 @@ protected:
|
||||
if (!s_compiledErc20)
|
||||
{
|
||||
vector<string> errors;
|
||||
s_compiledErc20.reset(new bytes(compileLLL(erc20Code, dev::test::Options::get().optimize, &errors)));
|
||||
s_compiledErc20.reset(new bytes(compileLLL(erc20Code, dev::test::Options::get().evmVersion(), dev::test::Options::get().optimize, &errors)));
|
||||
BOOST_REQUIRE(errors.empty());
|
||||
}
|
||||
sendMessage(*s_compiledErc20, true);
|
||||
|
||||
@@ -76,6 +76,7 @@ void testConstantOptimizer()
|
||||
ConstantOptimisationMethod::optimiseConstants(
|
||||
isCreation,
|
||||
runs,
|
||||
EVMVersion{},
|
||||
assembly,
|
||||
const_cast<AssemblyItems&>(assembly.items())
|
||||
);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
* Tests for the Solidity optimizer.
|
||||
*/
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libevmasm/CommonSubexpressionEliminator.h>
|
||||
#include <libevmasm/PeepholeOptimiser.h>
|
||||
#include <libevmasm/JumpdestRemover.h>
|
||||
@@ -916,7 +918,7 @@ BOOST_AUTO_TEST_CASE(jumpdest_removal_subassemblies)
|
||||
main.append(t1.toSubAssemblyTag(subId));
|
||||
main.append(u256(8));
|
||||
|
||||
main.optimise(true);
|
||||
main.optimise(true, dev::test::Options::get().evmVersion());
|
||||
|
||||
AssemblyItems expectationMain{
|
||||
AssemblyItem(PushSubSize, 0),
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include <test/libjulia/Common.h>
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libjulia/optimiser/Disambiguator.h>
|
||||
|
||||
#include <libsolidity/parsing/Scanner.h>
|
||||
@@ -61,7 +63,12 @@ pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::julia::test:
|
||||
{
|
||||
BOOST_REQUIRE(errorReporter.errors().empty());
|
||||
auto analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
|
||||
assembly::AsmAnalyzer analyzer(*analysisInfo, errorReporter, flavour);
|
||||
assembly::AsmAnalyzer analyzer(
|
||||
*analysisInfo,
|
||||
errorReporter,
|
||||
dev::test::Options::get().evmVersion(),
|
||||
flavour
|
||||
);
|
||||
if (analyzer.analyze(*parserResult))
|
||||
{
|
||||
BOOST_REQUIRE(errorReporter.errors().empty());
|
||||
|
||||
@@ -56,7 +56,12 @@ bool parse(string const& _source, ErrorReporter& errorReporter)
|
||||
if (parserResult)
|
||||
{
|
||||
assembly::AsmAnalysisInfo analysisInfo;
|
||||
return (assembly::AsmAnalyzer(analysisInfo, errorReporter, assembly::AsmFlavour::IULIA)).analyze(*parserResult);
|
||||
return (assembly::AsmAnalyzer(
|
||||
analysisInfo,
|
||||
errorReporter,
|
||||
dev::test::Options::get().evmVersion(),
|
||||
assembly::AsmFlavour::IULIA
|
||||
)).analyze(*parserResult);
|
||||
}
|
||||
}
|
||||
catch (FatalError const&)
|
||||
|
||||
@@ -20,11 +20,16 @@
|
||||
* Unit tests for the LLL compiler.
|
||||
*/
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libdevcore/FixedHash.h>
|
||||
|
||||
#include <liblll/Compiler.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <liblll/Compiler.h>
|
||||
#include <libdevcore/FixedHash.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -41,7 +46,7 @@ namespace
|
||||
bool successCompile(string const& _sourceCode)
|
||||
{
|
||||
vector<string> errors;
|
||||
bytes bytecode = eth::compileLLL(_sourceCode, false, &errors);
|
||||
bytes bytecode = eth::compileLLL(_sourceCode, dev::test::Options::get().evmVersion(), false, &errors);
|
||||
if (!errors.empty())
|
||||
return false;
|
||||
if (bytecode.empty())
|
||||
@@ -353,7 +358,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_functional)
|
||||
|
||||
for (size_t i = 0; i < opcodes_bytecode.size(); i++) {
|
||||
vector<string> errors;
|
||||
bytes code = eth::compileLLL(opcodes_lll[i], false, &errors);
|
||||
bytes code = eth::compileLLL(opcodes_lll[i], dev::test::Options::get().evmVersion(), false, &errors);
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
|
||||
|
||||
@@ -641,7 +646,7 @@ BOOST_AUTO_TEST_CASE(valid_opcodes_asm)
|
||||
|
||||
for (size_t i = 0; i < opcodes_bytecode.size(); i++) {
|
||||
vector<string> errors;
|
||||
bytes code = eth::compileLLL(opcodes_lll[i], false, &errors);
|
||||
bytes code = eth::compileLLL(opcodes_lll[i], dev::test::Options::get().evmVersion(), false, &errors);
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
|
||||
|
||||
|
||||
+167
-109
@@ -20,10 +20,13 @@
|
||||
* End to end tests for LLL.
|
||||
*/
|
||||
|
||||
#include <test/liblll/ExecutionFramework.h>
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/liblll/ExecutionFramework.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -583,24 +586,34 @@ BOOST_AUTO_TEST_CASE(allgas)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(send_two_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(send 0xdead 42))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callFallbackWithValue(42);
|
||||
BOOST_CHECK(balanceAt(Address(0xdead)) == 42);
|
||||
// "send" does not retain enough gas to be able to pay for account creation.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(send 0xdead 42))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callFallbackWithValue(42);
|
||||
BOOST_CHECK(balanceAt(Address(0xdead)) == 42);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(send_three_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(send allgas 0xdead 42))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callFallbackWithValue(42);
|
||||
BOOST_CHECK(balanceAt(Address(0xdead)) == 42);
|
||||
// "send" does not retain enough gas to be able to pay for account creation.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(send allgas 0xdead 42))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callFallbackWithValue(42);
|
||||
BOOST_CHECK(balanceAt(Address(0xdead)) == 42);
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for edge case that previously failed
|
||||
@@ -708,56 +721,76 @@ BOOST_AUTO_TEST_CASE(msg_four_args)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(msg_three_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(when (= 0 (calldatasize))
|
||||
(return (msg (address) 42 0xff)))
|
||||
(return (callvalue))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
|
||||
// "msg" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(when (= 0 (calldatasize))
|
||||
(return (msg (address) 42 0xff)))
|
||||
(return (callvalue))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(msg_two_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(when (= 0 (calldatasize))
|
||||
(return (msg (address) 0xff)))
|
||||
(return 42)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
|
||||
// "msg" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(when (= 0 (calldatasize))
|
||||
(return (msg (address) 0xff)))
|
||||
(return 42)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create_one_arg)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(call allgas
|
||||
(create (returnlll (return 42)))
|
||||
0 0 0 0x00 0x20)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
|
||||
// "call" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(call allgas
|
||||
(create (returnlll (return 42)))
|
||||
0 0 0 0x00 0x20)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(u256(42)));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create_two_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(call allgas
|
||||
(create 42 (returnlll (return (balance (address)))))
|
||||
0 0 0 0x00 0x20)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
|
||||
// "call" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(call allgas
|
||||
(create 42 (returnlll (return (balance (address)))))
|
||||
0 0 0 0x00 0x20)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallbackWithValue(42) == encodeArgs(u256(42)));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha3_two_args)
|
||||
@@ -822,77 +855,102 @@ BOOST_AUTO_TEST_CASE(makeperm) // Covers makeperm (implicit), permcount and perm
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ecrecover)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(return
|
||||
(ecrecover
|
||||
; Hash of 'hello world'
|
||||
0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad
|
||||
; v = 1 + 27
|
||||
0x1c
|
||||
; r
|
||||
0xdebaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215
|
||||
; s
|
||||
0x61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(fromHex("0x8743523d96a1b2cbe0c6909653a56da18ed484af")));
|
||||
// "ecrecover" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(return
|
||||
(ecrecover
|
||||
; Hash of 'hello world'
|
||||
0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad
|
||||
; v = 1 + 27
|
||||
0x1c
|
||||
; r
|
||||
0xdebaaa0cddb321b2dcaaf846d39605de7b97e77ba6106587855b9106cb104215
|
||||
; s
|
||||
0x61a22d94fa8b8a687ff9c911c844d1c016d1a685a9166858f9c7c1bc85128aca)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(fromHex("0x8743523d96a1b2cbe0c6909653a56da18ed484af")));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha256_two_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(lit 0x20 "abcdefghijklmnopqrstuvwxyzABCDEF")
|
||||
(lit 0x40 "GHIJKLMNOPQRSTUVWXYZ0123456789?!")
|
||||
(sha256 0x20 0x40)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xcf25a9fe3d86ae228c226c81d2d8c64c687cd6dc4586d10d8e7e4e5b6706d429")));
|
||||
// "sha256" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(lit 0x20 "abcdefghijklmnopqrstuvwxyzABCDEF")
|
||||
(lit 0x40 "GHIJKLMNOPQRSTUVWXYZ0123456789?!")
|
||||
(sha256 0x20 0x40)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xcf25a9fe3d86ae228c226c81d2d8c64c687cd6dc4586d10d8e7e4e5b6706d429")));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ripemd160_two_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(lit 0x20 "abcdefghijklmnopqrstuvwxyzABCDEF")
|
||||
(lit 0x40 "GHIJKLMNOPQRSTUVWXYZ0123456789?!")
|
||||
(ripemd160 0x20 0x40)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0x36c6b90a49e17d4c1e1b0e634ec74124d9b207da")));
|
||||
// "ripemd160" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(lit 0x20 "abcdefghijklmnopqrstuvwxyzABCDEF")
|
||||
(lit 0x40 "GHIJKLMNOPQRSTUVWXYZ0123456789?!")
|
||||
(ripemd160 0x20 0x40)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0x36c6b90a49e17d4c1e1b0e634ec74124d9b207da")));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(sha256_one_arg)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(sha256 0x6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xcfd2f1fad75a1978da0a444883db7251414b139f31f5a04704c291fdb0e175e6")));
|
||||
// "sha256" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(sha256 0x6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xcfd2f1fad75a1978da0a444883db7251414b139f31f5a04704c291fdb0e175e6")));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ripemd160_one_arg)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(ripemd160 0x6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xac5ab22e07b0fb80c69b6207902f725e2507e546")));
|
||||
// "ripemd160" does not retain enough gas.
|
||||
// Disabling for non-tangerineWhistle VMs.
|
||||
if (dev::test::Options::get().evmVersion().canOverchargeGasForCall())
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(ripemd160 0x6162636465666768696a6b6c6d6e6f707172737475767778797a414243444546)
|
||||
(return 0x00 0x20)))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callFallback() == encodeArgs(
|
||||
fromHex("0xac5ab22e07b0fb80c69b6207902f725e2507e546")));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(wei_szabo_finney_ether)
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
BOOST_REQUIRE(_libraryAddresses.empty());
|
||||
|
||||
std::vector<std::string> errors;
|
||||
bytes bytecode = eth::compileLLL(_sourceCode, m_optimize, &errors);
|
||||
bytes bytecode = eth::compileLLL(_sourceCode, dev::test::Options::get().evmVersion(), m_optimize, &errors);
|
||||
if (!errors.empty())
|
||||
{
|
||||
for (auto const& error: errors)
|
||||
|
||||
@@ -20,12 +20,16 @@
|
||||
* Tests for the json ast output.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/interface/Exceptions.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolidity/ast/ASTJsonConverter.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace dev
|
||||
@@ -41,6 +45,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C {}");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -52,6 +57,7 @@ BOOST_AUTO_TEST_CASE(source_location)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { function f() { var x = 2; x++; } }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -66,6 +72,7 @@ BOOST_AUTO_TEST_CASE(inheritance_specifier)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C1 {} contract C2 is C1 {}");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -81,6 +88,7 @@ BOOST_AUTO_TEST_CASE(using_for_directive)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "library L {} contract C { using L for uint; }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -98,6 +106,7 @@ BOOST_AUTO_TEST_CASE(enum_value)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { enum E { A, B } }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -115,6 +124,7 @@ BOOST_AUTO_TEST_CASE(modifier_definition)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -129,6 +139,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -145,6 +156,7 @@ BOOST_AUTO_TEST_CASE(event_definition)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { event E(); }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -159,6 +171,7 @@ BOOST_AUTO_TEST_CASE(array_type_name)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { uint[] i; }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -172,6 +185,7 @@ BOOST_AUTO_TEST_CASE(placeholder_statement)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { modifier M { _; } }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -185,6 +199,7 @@ BOOST_AUTO_TEST_CASE(non_utf8)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -204,6 +219,7 @@ BOOST_AUTO_TEST_CASE(function_type)
|
||||
"contract C { function f(function() external payable returns (uint) x) "
|
||||
"returns (function() external constant returns (uint)) {} }"
|
||||
);
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 1;
|
||||
@@ -244,6 +260,7 @@ BOOST_AUTO_TEST_CASE(documentation)
|
||||
" /** Some comment on fn.*/ function fn() public {}"
|
||||
"}"
|
||||
);
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
c.parseAndAnalyze();
|
||||
map<string, unsigned> sourceIndices;
|
||||
sourceIndices["a"] = 0;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolidity/interface/SourceReferenceFormatter.h>
|
||||
|
||||
@@ -46,6 +48,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
|
||||
{
|
||||
m_compiler.reset();
|
||||
m_compiler.addSource("", _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source);
|
||||
m_compiler.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
if (!m_compiler.parse())
|
||||
{
|
||||
BOOST_ERROR("Parsing contract failed in analysis test suite:" + formatErrors());
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
* Unit tests for Assembly Items from evmasm/Assembly.h
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libevmasm/SourceLocation.h>
|
||||
#include <libevmasm/Assembly.h>
|
||||
|
||||
#include <libsolidity/parsing/Scanner.h>
|
||||
#include <libsolidity/parsing/Parser.h>
|
||||
#include <libsolidity/analysis/NameAndTypeResolver.h>
|
||||
@@ -33,6 +33,11 @@
|
||||
#include <libsolidity/analysis/TypeChecker.h>
|
||||
#include <libsolidity/interface/ErrorReporter.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::eth;
|
||||
|
||||
@@ -46,7 +51,7 @@ namespace test
|
||||
namespace
|
||||
{
|
||||
|
||||
eth::AssemblyItems compileContract(const string& _sourceCode)
|
||||
eth::AssemblyItems compileContract(string const& _sourceCode)
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
@@ -69,7 +74,7 @@ eth::AssemblyItems compileContract(const string& _sourceCode)
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
TypeChecker checker(errorReporter);
|
||||
TypeChecker checker(dev::test::Options::get().evmVersion(), errorReporter);
|
||||
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract));
|
||||
if (!Error::containsOnlyWarnings(errorReporter.errors()))
|
||||
return AssemblyItems();
|
||||
@@ -77,7 +82,7 @@ eth::AssemblyItems compileContract(const string& _sourceCode)
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
Compiler compiler;
|
||||
Compiler compiler(dev::test::Options::get().evmVersion());
|
||||
compiler.compileContract(*contract, map<ContractDefinition const*, Assembly const*>{}, bytes());
|
||||
|
||||
return compiler.runtimeAssemblyItems();
|
||||
|
||||
@@ -49,13 +49,14 @@ public:
|
||||
m_compiler.reset(false);
|
||||
m_compiler.addSource("", "pragma solidity >=0.0;\n" + _sourceCode);
|
||||
m_compiler.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
|
||||
|
||||
AssemblyItems const* items = m_compiler.runtimeAssemblyItems(m_compiler.lastContractName());
|
||||
ASTNode const& sourceUnit = m_compiler.ast("");
|
||||
BOOST_REQUIRE(items != nullptr);
|
||||
m_gasCosts = GasEstimator::breakToStatementLevel(
|
||||
GasEstimator::structuralEstimation(*items, vector<ASTNode const*>({&sourceUnit})),
|
||||
GasEstimator(dev::test::Options::get().evmVersion()).structuralEstimation(*items, vector<ASTNode const*>({&sourceUnit})),
|
||||
{&sourceUnit}
|
||||
);
|
||||
}
|
||||
@@ -64,7 +65,7 @@ public:
|
||||
{
|
||||
compileAndRun(_sourceCode);
|
||||
auto state = make_shared<KnownState>();
|
||||
PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()));
|
||||
PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()), dev::test::Options::get().evmVersion());
|
||||
GasMeter::GasConsumption gas = meter.estimateMax(0, state);
|
||||
u256 bytecodeSize(m_compiler.runtimeObject(m_compiler.lastContractName()).bytecode.size());
|
||||
// costs for deployment
|
||||
@@ -73,7 +74,7 @@ public:
|
||||
gas += gasForTransaction(m_compiler.object(m_compiler.lastContractName()).bytecode, true);
|
||||
|
||||
BOOST_REQUIRE(!gas.isInfinite);
|
||||
BOOST_CHECK(gas.value == m_gasUsed);
|
||||
BOOST_CHECK_EQUAL(gas.value, m_gasUsed);
|
||||
}
|
||||
|
||||
/// Compares the gas computed by PathGasMeter for the given signature (but unknown arguments)
|
||||
@@ -90,12 +91,12 @@ public:
|
||||
gas = max(gas, gasForTransaction(hash.asBytes() + arguments, false));
|
||||
}
|
||||
|
||||
gas += GasEstimator::functionalEstimation(
|
||||
gas += GasEstimator(dev::test::Options::get().evmVersion()).functionalEstimation(
|
||||
*m_compiler.runtimeAssemblyItems(m_compiler.lastContractName()),
|
||||
_sig
|
||||
);
|
||||
BOOST_REQUIRE(!gas.isInfinite);
|
||||
BOOST_CHECK(gas.value == m_gasUsed);
|
||||
BOOST_CHECK_EQUAL(gas.value, m_gasUsed);
|
||||
}
|
||||
|
||||
static GasMeter::GasConsumption gasForTransaction(bytes const& _data, bool _isCreation)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <test/libsolidity/ErrorCheck.h>
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/interface/Exceptions.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
@@ -44,6 +45,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
||||
{
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -52,6 +54,7 @@ BOOST_AUTO_TEST_CASE(regular_import)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C {} pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -60,6 +63,7 @@ BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract C { D d; } pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
}
|
||||
|
||||
@@ -69,6 +73,7 @@ BOOST_AUTO_TEST_CASE(import_is_transitive)
|
||||
c.addSource("a", "contract C { } pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\"; pragma solidity >=0.0;");
|
||||
c.addSource("c", "import \"b\"; contract D is C {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -77,6 +82,7 @@ BOOST_AUTO_TEST_CASE(circular_import)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "import \"b\"; contract C { D d; } pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\"; contract D { C c; } pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -86,6 +92,7 @@ BOOST_AUTO_TEST_CASE(relative_import)
|
||||
c.addSource("a", "import \"./dir/b\"; contract A is B {} pragma solidity >=0.0;");
|
||||
c.addSource("dir/b", "contract B {} pragma solidity >=0.0;");
|
||||
c.addSource("dir/c", "import \"../a\"; contract C is A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -94,6 +101,7 @@ BOOST_AUTO_TEST_CASE(relative_import_multiplex)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract A {} pragma solidity >=0.0;");
|
||||
c.addSource("dir/a/b/c", "import \"../../.././a\"; contract B is A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -102,6 +110,7 @@ BOOST_AUTO_TEST_CASE(simple_alias)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract A {} pragma solidity >=0.0;");
|
||||
c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() { x.A r = x.A(20); } } pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -111,6 +120,7 @@ BOOST_AUTO_TEST_CASE(library_name_clash)
|
||||
c.addSource("a", "library A {} pragma solidity >=0.0;");
|
||||
c.addSource("b", "library A {} pragma solidity >=0.0;");
|
||||
c.addSource("c", "import {A} from \"./a\"; import {A} from \"./b\";");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
}
|
||||
|
||||
@@ -119,6 +129,7 @@ BOOST_AUTO_TEST_CASE(library_name_clash_with_contract)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract A {} pragma solidity >=0.0;");
|
||||
c.addSource("b", "library A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -128,6 +139,7 @@ BOOST_AUTO_TEST_CASE(complex_import)
|
||||
c.addSource("a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; "
|
||||
"contract D is b { function f(c.S var1, x.C.S var2, C.S var3) internal {} } pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -136,14 +148,19 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import)
|
||||
CompilerStack c;
|
||||
c.addSource("a", "contract A {} pragma solidity >=0.0;");
|
||||
c.addSource("b", "import \"a\"; contract A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
c.addSource("b", "import \"a\" as A; contract A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
c.addSource("b", "import {A as b} from \"a\"; contract b {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
c.addSource("b", "import {A} from \"a\"; contract A {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
c.addSource("b", "import {A} from \"a\"; contract B {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -155,6 +172,7 @@ BOOST_AUTO_TEST_CASE(remappings)
|
||||
c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;");
|
||||
c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;");
|
||||
c.addSource("Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -166,6 +184,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings)
|
||||
c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;");
|
||||
c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;");
|
||||
c.addSource("s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -174,6 +193,7 @@ BOOST_AUTO_TEST_CASE(filename_with_period)
|
||||
CompilerStack c;
|
||||
c.addSource("a/a.sol", "import \".b.sol\"; contract A is B {} pragma solidity >=0.0;");
|
||||
c.addSource("a/.b.sol", "contract B {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
}
|
||||
|
||||
@@ -185,6 +205,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_pres
|
||||
c.addSource("vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;");
|
||||
c.addSource("vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;");
|
||||
c.addSource("vendor/foo_2.0.0/foo.sol", "contract Foo2 {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
}
|
||||
|
||||
@@ -196,6 +217,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
||||
c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
||||
c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
||||
c.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
CompilerStack d;
|
||||
d.setRemappings(vector<string>{"a/b:x=e", "a:x/y/z=d"});
|
||||
@@ -203,6 +225,7 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent)
|
||||
d.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;");
|
||||
d.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;");
|
||||
d.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;");
|
||||
d.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(d.compile());
|
||||
}
|
||||
|
||||
@@ -212,6 +235,7 @@ BOOST_AUTO_TEST_CASE(shadowing_via_import)
|
||||
c.addSource("a", "library A {} pragma solidity >=0.0;");
|
||||
c.addSource("b", "library A {} pragma solidity >=0.0;");
|
||||
c.addSource("c", "import {A} from \"./a\"; import {A} from \"./b\";");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!c.compile());
|
||||
}
|
||||
|
||||
@@ -225,6 +249,7 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports)
|
||||
contract C {
|
||||
}
|
||||
)");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
size_t errorCount = 0;
|
||||
for (auto const& e: c.errors())
|
||||
@@ -251,6 +276,7 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports)
|
||||
contract C {
|
||||
}
|
||||
)");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
auto numErrors = c.errors().size();
|
||||
// Sometimes we get the prerelease warning, sometimes not.
|
||||
@@ -274,6 +300,7 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_alias)
|
||||
pragma solidity >=0.0;
|
||||
import {C as msg} from "B.sol";
|
||||
)");
|
||||
c.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(c.compile());
|
||||
auto numErrors = c.errors().size();
|
||||
// Sometimes we get the prerelease warning, sometimes not.
|
||||
|
||||
@@ -55,7 +55,7 @@ boost::optional<Error> parseAndReturnFirstError(
|
||||
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
|
||||
)
|
||||
{
|
||||
AssemblyStack stack(_language);
|
||||
AssemblyStack stack(dev::test::Options::get().evmVersion(), _language);
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
@@ -117,7 +117,7 @@ Error expectError(
|
||||
|
||||
void parsePrintCompare(string const& _source, bool _canWarn = false)
|
||||
{
|
||||
AssemblyStack stack;
|
||||
AssemblyStack stack(dev::test::Options::get().evmVersion());
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
|
||||
if (_canWarn)
|
||||
BOOST_REQUIRE(Error::containsOnlyWarnings(stack.errors()));
|
||||
@@ -567,7 +567,7 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
|
||||
{
|
||||
string source = "{ let x := \"\\u1bac\" }";
|
||||
string parsed = "{\n let x := \"\\xe1\\xae\\xac\"\n}";
|
||||
AssemblyStack stack;
|
||||
AssemblyStack stack(dev::test::Options::get().evmVersion());
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", source));
|
||||
BOOST_REQUIRE(stack.errors().empty());
|
||||
BOOST_CHECK_EQUAL(stack.print(), parsed);
|
||||
@@ -783,9 +783,9 @@ BOOST_AUTO_TEST_CASE(shift)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(shift_constantinople_warning)
|
||||
{
|
||||
CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", Warning, "The \"shl\" instruction is only available after the Constantinople hard fork");
|
||||
CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", Warning, "The \"shr\" instruction is only available after the Constantinople hard fork");
|
||||
CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", Warning, "The \"sar\" instruction is only available after the Constantinople hard fork");
|
||||
CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", Warning, "The \"shl\" instruction is only available for Constantinople-compatible VMs.");
|
||||
CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", Warning, "The \"shr\" instruction is only available for Constantinople-compatible VMs.");
|
||||
CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", Warning, "The \"sar\" instruction is only available for Constantinople-compatible VMs.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(jump_warning)
|
||||
|
||||
@@ -46,6 +46,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
|
||||
)";
|
||||
CompilerStack compilerStack;
|
||||
compilerStack.addSource("", std::string(sourceCode));
|
||||
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
|
||||
@@ -72,6 +73,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
|
||||
)";
|
||||
CompilerStack compilerStack;
|
||||
compilerStack.addSource("", std::string(sourceCode));
|
||||
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
bytes const& bytecode = compilerStack.runtimeObject("test").bytecode;
|
||||
@@ -106,6 +108,7 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
|
||||
}
|
||||
)";
|
||||
compilerStack.addSource("B", std::string(sourceCode));
|
||||
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
@@ -144,6 +147,7 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
|
||||
}
|
||||
)";
|
||||
compilerStack.addSource("C", std::string(sourceCode));
|
||||
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ public:
|
||||
{
|
||||
m_compilerStack.reset(false);
|
||||
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code);
|
||||
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
m_compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
|
||||
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
|
||||
|
||||
Json::Value generatedInterface = m_compilerStack.contractABI(m_compilerStack.lastContractName());
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
m_compiler.reset(false);
|
||||
m_compiler.addSource("", sourceCode);
|
||||
m_compiler.setLibraries(_libraryAddresses);
|
||||
m_compiler.setEVMVersion(m_evmVersion);
|
||||
m_compiler.setOptimiserSettings(m_optimize, m_optimizeRuns);
|
||||
if (!m_compiler.compile())
|
||||
{
|
||||
|
||||
@@ -132,7 +132,7 @@ bytes compileFirstExpression(
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
ErrorReporter errorReporter(errors);
|
||||
TypeChecker typeChecker(errorReporter);
|
||||
TypeChecker typeChecker(dev::test::Options::get().evmVersion(), errorReporter);
|
||||
BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract));
|
||||
}
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
@@ -141,7 +141,7 @@ bytes compileFirstExpression(
|
||||
FirstExpressionExtractor extractor(*contract);
|
||||
BOOST_REQUIRE(extractor.expression() != nullptr);
|
||||
|
||||
CompilerContext context;
|
||||
CompilerContext context(dev::test::Options::get().evmVersion());
|
||||
context.resetVisitedNodes(contract);
|
||||
context.setInheritanceHierarchy(inheritanceHierarchy);
|
||||
unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <libsolidity/ast/AST.h>
|
||||
|
||||
#include <libdevcore/SHA3.h>
|
||||
@@ -7100,11 +7102,13 @@ BOOST_AUTO_TEST_CASE(returndatacopy_as_variable)
|
||||
char const* text = R"(
|
||||
contract c { function f() public { uint returndatasize; assembly { returndatasize }}}
|
||||
)";
|
||||
CHECK_ALLOW_MULTI(text, (std::vector<std::pair<Error::Type, std::string>>{
|
||||
vector<pair<Error::Type, std::string>> expectations(vector<pair<Error::Type, std::string>>{
|
||||
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"},
|
||||
{Error::Type::DeclarationError, "Unbalanced stack"},
|
||||
{Error::Type::Warning, "only available after the Metropolis"}
|
||||
}));
|
||||
{Error::Type::DeclarationError, "Unbalanced stack"}
|
||||
});
|
||||
if (!dev::test::Options::get().evmVersion().supportsReturndata())
|
||||
expectations.emplace_back(make_pair(Error::Type::Warning, std::string("\"returndatasize\" instruction is only available for Byzantium-compatible")));
|
||||
CHECK_ALLOW_MULTI(text, expectations);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create2_as_variable)
|
||||
@@ -7114,7 +7118,7 @@ BOOST_AUTO_TEST_CASE(create2_as_variable)
|
||||
)";
|
||||
CHECK_ALLOW_MULTI(text, (std::vector<std::pair<Error::Type, std::string>>{
|
||||
{Error::Type::Warning, "Variable is shadowed in inline assembly by an instruction of the same name"},
|
||||
{Error::Type::Warning, "only available after the Metropolis"},
|
||||
{Error::Type::Warning, "The \"create2\" instruction is not supported by the VM version"},
|
||||
{Error::Type::DeclarationError, "Unbalanced stack"}
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
{
|
||||
m_compilerStack.reset(false);
|
||||
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code);
|
||||
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
|
||||
|
||||
Json::Value generatedDocumentation;
|
||||
@@ -67,6 +68,7 @@ public:
|
||||
{
|
||||
m_compilerStack.reset(false);
|
||||
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code);
|
||||
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
|
||||
BOOST_CHECK(!m_compilerStack.parseAndAnalyze());
|
||||
BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError));
|
||||
}
|
||||
|
||||
@@ -724,6 +724,43 @@ BOOST_AUTO_TEST_CASE(library_linking)
|
||||
BOOST_CHECK(contract["evm"]["bytecode"]["linkReferences"]["library2.sol"]["L2"][0].isObject());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(evm_version)
|
||||
{
|
||||
auto inputForVersion = [](string const& _version)
|
||||
{
|
||||
return R"(
|
||||
{
|
||||
"language": "Solidity",
|
||||
"sources": { "fileA": { "content": "contract A { }" } },
|
||||
"settings": {
|
||||
)" + _version + R"(
|
||||
"outputSelection": {
|
||||
"fileA": {
|
||||
"A": [ "metadata" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)";
|
||||
};
|
||||
Json::Value result;
|
||||
result = compile(inputForVersion("\"evmVersion\": \"homestead\","));
|
||||
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"homestead\"") != string::npos);
|
||||
result = compile(inputForVersion("\"evmVersion\": \"tangerineWhistle\","));
|
||||
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"tangerineWhistle\"") != string::npos);
|
||||
result = compile(inputForVersion("\"evmVersion\": \"spuriousDragon\","));
|
||||
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"spuriousDragon\"") != string::npos);
|
||||
result = compile(inputForVersion("\"evmVersion\": \"byzantium\","));
|
||||
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"byzantium\"") != string::npos);
|
||||
// test default
|
||||
result = compile(inputForVersion(""));
|
||||
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"byzantium\"") != string::npos);
|
||||
// test invalid
|
||||
result = compile(inputForVersion("\"evmVersion\": \"invalid\","));
|
||||
BOOST_CHECK(result["errors"][0]["message"].asString() == "Invalid EVM version requested.");
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <test/libsolidity/AnalysisFramework.h>
|
||||
|
||||
#include <test/TestHelper.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -423,7 +425,10 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
|
||||
}
|
||||
}
|
||||
)";
|
||||
CHECK_WARNING(text, "only available after the Metropolis");
|
||||
if (!dev::test::Options::get().evmVersion().hasStaticCall())
|
||||
CHECK_WARNING(text, "\"staticcall\" instruction is only available for Byzantium-compatible");
|
||||
else
|
||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(assembly_jump)
|
||||
|
||||
Reference in New Issue
Block a user