aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/ExecutionFramework.h67
-rw-r--r--test/RPCSession.cpp27
-rw-r--r--test/RPCSession.h1
-rw-r--r--test/contracts/AuctionRegistrar.cpp2
-rw-r--r--test/contracts/ContractInterface.h99
-rw-r--r--test/libevmasm/Optimiser.cpp14
-rw-r--r--test/liblll/Compiler.cpp532
-rw-r--r--test/libsolidity/AnalysisFramework.cpp2
-rw-r--r--test/libsolidity/Assembly.cpp2
-rw-r--r--test/libsolidity/GasMeter.cpp14
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp2
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp344
-rw-r--r--test/libsolidity/SolidityExecutionFramework.h2
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp87
-rw-r--r--test/libsolidity/SolidityNatspecJSON.cpp4
-rw-r--r--test/libsolidity/ViewPureChecker.cpp7
16 files changed, 1112 insertions, 94 deletions
diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h
index cc25bea7..2c61c0a6 100644
--- a/test/ExecutionFramework.h
+++ b/test/ExecutionFramework.h
@@ -172,78 +172,13 @@ public:
{
return bytes();
}
+
//@todo might be extended in the future
template <class Arg>
static bytes encodeDyn(Arg const& _arg)
{
return encodeArgs(u256(0x20), u256(_arg.size()), _arg);
}
- class ContractInterface
- {
- public:
- ContractInterface(ExecutionFramework& _framework): m_framework(_framework) {}
-
- void setNextValue(u256 const& _value) { m_nextValue = _value; }
-
- protected:
- template <class... Args>
- bytes const& call(std::string const& _sig, Args const&... _arguments)
- {
- auto const& ret = m_framework.callContractFunctionWithValue(_sig, m_nextValue, _arguments...);
- m_nextValue = 0;
- return ret;
- }
-
- void callString(std::string const& _name, std::string const& _arg)
- {
- BOOST_CHECK(call(_name + "(string)", u256(0x20), _arg.length(), _arg).empty());
- }
-
- void callStringAddress(std::string const& _name, std::string const& _arg1, u160 const& _arg2)
- {
- BOOST_CHECK(call(_name + "(string,address)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
- }
-
- void callStringAddressBool(std::string const& _name, std::string const& _arg1, u160 const& _arg2, bool _arg3)
- {
- BOOST_CHECK(call(_name + "(string,address,bool)", u256(0x60), _arg2, _arg3, _arg1.length(), _arg1).empty());
- }
-
- void callStringBytes32(std::string const& _name, std::string const& _arg1, h256 const& _arg2)
- {
- BOOST_CHECK(call(_name + "(string,bytes32)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
- }
-
- u160 callStringReturnsAddress(std::string const& _name, std::string const& _arg)
- {
- bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
- BOOST_REQUIRE(ret.size() == 0x20);
- BOOST_CHECK(std::count(ret.begin(), ret.begin() + 12, 0) == 12);
- return u160(u256(h256(ret)));
- }
-
- std::string callAddressReturnsString(std::string const& _name, u160 const& _arg)
- {
- bytesConstRef const ret(&call(_name + "(address)", _arg));
- BOOST_REQUIRE(ret.size() >= 0x40);
- u256 offset(h256(ret.cropped(0, 0x20)));
- BOOST_REQUIRE_EQUAL(offset, 0x20);
- u256 len(h256(ret.cropped(0x20, 0x20)));
- BOOST_REQUIRE_EQUAL(ret.size(), 0x40 + ((len + 0x1f) / 0x20) * 0x20);
- return ret.cropped(0x40, size_t(len)).toString();
- }
-
- h256 callStringReturnsBytes32(std::string const& _name, std::string const& _arg)
- {
- bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
- BOOST_REQUIRE(ret.size() == 0x20);
- return h256(ret);
- }
-
- private:
- u256 m_nextValue;
- ExecutionFramework& m_framework;
- };
private:
template <class CppFunction, class... Args>
diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp
index 768c8c4b..c06c3997 100644
--- a/test/RPCSession.cpp
+++ b/test/RPCSession.cpp
@@ -74,7 +74,10 @@ IPCSocket::IPCSocket(string const& _path): m_path(_path)
BOOST_FAIL("Error creating IPC socket object");
if (connect(m_socket, reinterpret_cast<struct sockaddr const*>(&saun), sizeof(struct sockaddr_un)) < 0)
+ {
+ close(m_socket);
BOOST_FAIL("Error connecting to IPC socket: " << _path);
+ }
#endif
}
@@ -236,7 +239,10 @@ void RPCSession::test_setChainParams(vector<string> const& _accounts)
"0000000000000000000000000000000000000001": { "wei": "1", "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "wei": "1", "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "wei": "1", "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
- "0000000000000000000000000000000000000004": { "wei": "1", "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
+ "0000000000000000000000000000000000000004": { "wei": "1", "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
+ "0000000000000000000000000000000000000006": { "wei": "1", "precompiled": { "name": "alt_bn128_G1_add", "linear": { "base": 15, "word": 3 } } },
+ "0000000000000000000000000000000000000007": { "wei": "1", "precompiled": { "name": "alt_bn128_G1_mul", "linear": { "base": 15, "word": 3 } } },
+ "0000000000000000000000000000000000000008": { "wei": "1", "precompiled": { "name": "alt_bn128_pairing_product", "linear": { "base": 15, "word": 3 } } }
}
}
)";
@@ -333,22 +339,25 @@ Json::Value RPCSession::rpcCall(string const& _methodName, vector<string> const&
return result["result"];
}
+string const& RPCSession::accountCreate()
+{
+ m_accounts.push_back(personal_newAccount(""));
+ personal_unlockAccount(m_accounts.back(), "", 100000);
+ return m_accounts.back();
+}
+
string const& RPCSession::accountCreateIfNotExists(size_t _id)
{
- if (_id >= m_accounts.size())
- {
- m_accounts.push_back(personal_newAccount(""));
- personal_unlockAccount(m_accounts.back(), "", 100000);
- }
+ while ((_id + 1) > m_accounts.size())
+ accountCreate();
return m_accounts[_id];
}
RPCSession::RPCSession(const string& _path):
m_ipcSocket(_path)
{
- string account = personal_newAccount("");
- personal_unlockAccount(account, "", 100000);
- m_accounts.push_back(account);
+ accountCreate();
+ // This will pre-fund the accounts create prior.
test_setChainParams(m_accounts);
}
diff --git a/test/RPCSession.h b/test/RPCSession.h
index eae6a09c..63f1dd21 100644
--- a/test/RPCSession.h
+++ b/test/RPCSession.h
@@ -121,6 +121,7 @@ public:
Json::Value rpcCall(std::string const& _methodName, std::vector<std::string> const& _args = std::vector<std::string>(), bool _canFail = false);
std::string const& account(size_t _id) const { return m_accounts.at(_id); }
+ std::string const& accountCreate();
std::string const& accountCreateIfNotExists(size_t _id);
private:
diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp
index 73a5d1ed..c9c744af 100644
--- a/test/contracts/AuctionRegistrar.cpp
+++ b/test/contracts/AuctionRegistrar.cpp
@@ -24,6 +24,7 @@
#include <tuple>
#include <boost/test/unit_test.hpp>
#include <test/libsolidity/SolidityExecutionFramework.h>
+#include <test/contracts/ContractInterface.h>
using namespace std;
using namespace dev::test;
@@ -230,7 +231,6 @@ protected:
BOOST_REQUIRE(!m_output.empty());
}
- using ContractInterface = SolidityExecutionFramework::ContractInterface;
class RegistrarInterface: public ContractInterface
{
public:
diff --git a/test/contracts/ContractInterface.h b/test/contracts/ContractInterface.h
new file mode 100644
index 00000000..052b0db2
--- /dev/null
+++ b/test/contracts/ContractInterface.h
@@ -0,0 +1,99 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <boost/test/unit_test.hpp>
+#include <test/ExecutionFramework.h>
+
+#include <functional>
+
+namespace dev
+{
+namespace test
+{
+
+class ContractInterface
+{
+public:
+ ContractInterface(ExecutionFramework& _framework): m_framework(_framework) {}
+
+ void setNextValue(u256 const& _value) { m_nextValue = _value; }
+
+protected:
+ template <class... Args>
+ bytes const& call(std::string const& _sig, Args const&... _arguments)
+ {
+ auto const& ret = m_framework.callContractFunctionWithValue(_sig, m_nextValue, _arguments...);
+ m_nextValue = 0;
+ return ret;
+ }
+
+ void callString(std::string const& _name, std::string const& _arg)
+ {
+ BOOST_CHECK(call(_name + "(string)", u256(0x20), _arg.length(), _arg).empty());
+ }
+
+ void callStringAddress(std::string const& _name, std::string const& _arg1, u160 const& _arg2)
+ {
+ BOOST_CHECK(call(_name + "(string,address)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
+ }
+
+ void callStringAddressBool(std::string const& _name, std::string const& _arg1, u160 const& _arg2, bool _arg3)
+ {
+ BOOST_CHECK(call(_name + "(string,address,bool)", u256(0x60), _arg2, _arg3, _arg1.length(), _arg1).empty());
+ }
+
+ void callStringBytes32(std::string const& _name, std::string const& _arg1, h256 const& _arg2)
+ {
+ BOOST_CHECK(call(_name + "(string,bytes32)", u256(0x40), _arg2, _arg1.length(), _arg1).empty());
+ }
+
+ u160 callStringReturnsAddress(std::string const& _name, std::string const& _arg)
+ {
+ bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
+ BOOST_REQUIRE(ret.size() == 0x20);
+ BOOST_CHECK(std::count(ret.begin(), ret.begin() + 12, 0) == 12);
+ return u160(u256(h256(ret)));
+ }
+
+ std::string callAddressReturnsString(std::string const& _name, u160 const& _arg)
+ {
+ bytesConstRef const ret(&call(_name + "(address)", _arg));
+ BOOST_REQUIRE(ret.size() >= 0x40);
+ u256 offset(h256(ret.cropped(0, 0x20)));
+ BOOST_REQUIRE_EQUAL(offset, 0x20);
+ u256 len(h256(ret.cropped(0x20, 0x20)));
+ BOOST_REQUIRE_EQUAL(ret.size(), 0x40 + ((len + 0x1f) / 0x20) * 0x20);
+ return ret.cropped(0x40, size_t(len)).toString();
+ }
+
+ h256 callStringReturnsBytes32(std::string const& _name, std::string const& _arg)
+ {
+ bytes const& ret = call(_name + "(string)", u256(0x20), _arg.length(), _arg);
+ BOOST_REQUIRE(ret.size() == 0x20);
+ return h256(ret);
+ }
+
+private:
+ u256 m_nextValue;
+ ExecutionFramework& m_framework;
+};
+
+}
+} // end namespaces
+
diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp
index 9dc49581..0ab95b08 100644
--- a/test/libevmasm/Optimiser.cpp
+++ b/test/libevmasm/Optimiser.cpp
@@ -841,6 +841,20 @@ BOOST_AUTO_TEST_CASE(peephole_double_push)
);
}
+BOOST_AUTO_TEST_CASE(peephole_pop_calldatasize)
+{
+ AssemblyItems items{
+ u256(4),
+ Instruction::CALLDATASIZE,
+ Instruction::LT,
+ Instruction::POP
+ };
+ PeepholeOptimiser peepOpt(items);
+ for (size_t i = 0; i < 3; i++)
+ BOOST_CHECK(peepOpt.optimise());
+ BOOST_CHECK(items.empty());
+}
+
BOOST_AUTO_TEST_CASE(jumpdest_removal)
{
AssemblyItems items{
diff --git a/test/liblll/Compiler.cpp b/test/liblll/Compiler.cpp
index 2d66bce1..ace97e15 100644
--- a/test/liblll/Compiler.cpp
+++ b/test/liblll/Compiler.cpp
@@ -24,6 +24,7 @@
#include <memory>
#include <boost/test/unit_test.hpp>
#include <liblll/Compiler.h>
+#include <libdevcore/FixedHash.h>
using namespace std;
@@ -37,9 +38,9 @@ namespace test
namespace
{
-bool successCompile(std::string const& _sourceCode)
+bool successCompile(string const& _sourceCode)
{
- std::vector<std::string> errors;
+ vector<string> errors;
bytes bytecode = eth::compileLLL(_sourceCode, false, &errors);
if (!errors.empty())
return false;
@@ -121,6 +122,533 @@ BOOST_AUTO_TEST_CASE(switch_inconsistent_return_count)
BOOST_CHECK(!successCompile(sourceCode));
}
+BOOST_AUTO_TEST_CASE(disallowed_asm_instructions)
+{
+ for (unsigned i = 1; i <= 32; i++)
+ BOOST_CHECK(!successCompile("(asm PUSH" + boost::lexical_cast<string>(i) + ")"));
+}
+
+BOOST_AUTO_TEST_CASE(disallowed_functional_asm_instructions)
+{
+ for (unsigned i = 1; i <= 32; i++)
+ BOOST_CHECK(!successCompile("(PUSH" + boost::lexical_cast<string>(i) + ")"));
+ for (unsigned i = 1; i <= 16; i++)
+ BOOST_CHECK(!successCompile("(DUP" + boost::lexical_cast<string>(i) + ")"));
+ for (unsigned i = 1; i <= 16; i++)
+ BOOST_CHECK(!successCompile("(SWAP" + boost::lexical_cast<string>(i) + ")"));
+ BOOST_CHECK(!successCompile("(JUMPDEST)"));
+}
+
+BOOST_AUTO_TEST_CASE(valid_opcodes_functional)
+{
+ vector<string> opcodes_bytecode {
+ "00",
+ "6000600001",
+ "6000600002",
+ "6000600003",
+ "6000600004",
+ "6000600005",
+ "6000600006",
+ "6000600007",
+ "60006000600008",
+ "60006000600009",
+ "600060000a",
+ "600060000b",
+ "6000600010",
+ "6000600011",
+ "6000600012",
+ "6000600013",
+ "6000600014",
+ "600015",
+ "6000600016",
+ "6000600017",
+ "6000600018",
+ "600019",
+ "600060001a",
+ "6000600020",
+ "30",
+ "600031",
+ "32",
+ "33",
+ "34",
+ "600035",
+ "36",
+ "60006000600037",
+ "38",
+ "60006000600039",
+ "3a",
+ "60003b",
+ "60006000600060003c",
+ "3d",
+ "6000600060003e",
+ "600040",
+ "41",
+ "42",
+ "43",
+ "44",
+ "45",
+ "600050",
+ "600051",
+ "6000600052",
+ "6000600053",
+ "600054",
+ "6000600055",
+ "600056",
+ "6000600057",
+ "58",
+ "59",
+ "5a",
+ "60ff",
+ "61ffff",
+ "62ffffff",
+ "63ffffffff",
+ "64ffffffffff",
+ "65ffffffffffff",
+ "66ffffffffffffff",
+ "67ffffffffffffffff",
+ "68ffffffffffffffffff",
+ "69ffffffffffffffffffff",
+ "6affffffffffffffffffffff",
+ "6bffffffffffffffffffffffff",
+ "6cffffffffffffffffffffffffff",
+ "6dffffffffffffffffffffffffffff",
+ "6effffffffffffffffffffffffffffff",
+ "6fffffffffffffffffffffffffffffffff",
+ "70ffffffffffffffffffffffffffffffffff",
+ "71ffffffffffffffffffffffffffffffffffff",
+ "72ffffffffffffffffffffffffffffffffffffff",
+ "73ffffffffffffffffffffffffffffffffffffffff",
+ "74ffffffffffffffffffffffffffffffffffffffffff",
+ "75ffffffffffffffffffffffffffffffffffffffffffff",
+ "76ffffffffffffffffffffffffffffffffffffffffffffff",
+ "77ffffffffffffffffffffffffffffffffffffffffffffffff",
+ "78ffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "79ffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7affffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "60006000a0",
+ "600060006000a1",
+ "6000600060006000a2",
+ "60006000600060006000a3",
+ "600060006000600060006000a4",
+ "600060006000f0",
+ "6000600060006000600060006000f1",
+ "6000600060006000600060006000f2",
+ "60006000f3",
+ "600060006000600060006000f4",
+ "600060006000600060006000fa",
+ "60006000fd",
+ "fe",
+ "6000ff"
+ };
+
+ vector<string> opcodes_lll {
+ "{ (STOP) }",
+ "{ (ADD 0 0) }",
+ "{ (MUL 0 0) }",
+ "{ (SUB 0 0) }",
+ "{ (DIV 0 0) }",
+ "{ (SDIV 0 0) }",
+ "{ (MOD 0 0) }",
+ "{ (SMOD 0 0) }",
+ "{ (ADDMOD 0 0 0) }",
+ "{ (MULMOD 0 0 0) }",
+ "{ (EXP 0 0) }",
+ "{ (SIGNEXTEND 0 0) }",
+ "{ (LT 0 0) }",
+ "{ (GT 0 0) }",
+ "{ (SLT 0 0) }",
+ "{ (SGT 0 0) }",
+ "{ (EQ 0 0) }",
+ "{ (ISZERO 0) }",
+ "{ (AND 0 0) }",
+ "{ (OR 0 0) }",
+ "{ (XOR 0 0) }",
+ "{ (NOT 0) }",
+ "{ (BYTE 0 0) }",
+ "{ (KECCAK256 0 0) }",
+ "{ (ADDRESS) }",
+ "{ (BALANCE 0) }",
+ "{ (ORIGIN) }",
+ "{ (CALLER) }",
+ "{ (CALLVALUE) }",
+ "{ (CALLDATALOAD 0) }",
+ "{ (CALLDATASIZE) }",
+ "{ (CALLDATACOPY 0 0 0) }",
+ "{ (CODESIZE) }",
+ "{ (CODECOPY 0 0 0) }",
+ "{ (GASPRICE) }",
+ "{ (EXTCODESIZE 0) }",
+ "{ (EXTCODECOPY 0 0 0 0) }",
+ "{ (RETURNDATASIZE) }",
+ "{ (RETURNDATACOPY 0 0 0) }",
+ "{ (BLOCKHASH 0) }",
+ "{ (COINBASE) }",
+ "{ (TIMESTAMP) }",
+ "{ (NUMBER) }",
+ "{ (DIFFICULTY) }",
+ "{ (GASLIMIT) }",
+ "{ (POP 0) }",
+ "{ (MLOAD 0) }",
+ "{ (MSTORE 0 0) }",
+ "{ (MSTORE8 0 0) }",
+ "{ (SLOAD 0) }",
+ "{ (SSTORE 0 0) }",
+ "{ (JUMP 0) }",
+ "{ (JUMPI 0 0) }",
+ "{ (PC) }",
+ "{ (MSIZE) }",
+ "{ (GAS) }",
+ "{ 0xff }",
+ "{ 0xffff }",
+ "{ 0xffffff }",
+ "{ 0xffffffff }",
+ "{ 0xffffffffff }",
+ "{ 0xffffffffffff }",
+ "{ 0xffffffffffffff }",
+ "{ 0xffffffffffffffff }",
+ "{ 0xffffffffffffffffff }",
+ "{ 0xffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }",
+ "{ (LOG0 0 0) }",
+ "{ (LOG1 0 0 0) }",
+ "{ (LOG2 0 0 0 0) }",
+ "{ (LOG3 0 0 0 0 0) }",
+ "{ (LOG4 0 0 0 0 0 0) }",
+ "{ (CREATE 0 0 0) }",
+ "{ (CALL 0 0 0 0 0 0 0) }",
+ "{ (CALLCODE 0 0 0 0 0 0 0) }",
+ "{ (RETURN 0 0) }",
+ "{ (DELEGATECALL 0 0 0 0 0 0) }",
+ "{ (STATICCALL 0 0 0 0 0 0) }",
+ "{ (REVERT 0 0) }",
+ "{ (INVALID) }",
+ "{ (SELFDESTRUCT 0) }"
+ };
+
+ for (size_t i = 0; i < opcodes_bytecode.size(); i++) {
+ vector<string> errors;
+ bytes code = eth::compileLLL(opcodes_lll[i], false, &errors);
+
+ BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
+
+ BOOST_CHECK_EQUAL(toHex(code), opcodes_bytecode[i]);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(valid_opcodes_asm)
+{
+ vector<string> opcodes_bytecode {
+ "00",
+ "01",
+ "02",
+ "03",
+ "04",
+ "05",
+ "06",
+ "07",
+ "08",
+ "09",
+ "0a",
+ "0b",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "15",
+ "16",
+ "17",
+ "18",
+ "19",
+ "1a",
+ "20",
+ "30",
+ "31",
+ "32",
+ "33",
+ "34",
+ "35",
+ "36",
+ "37",
+ "38",
+ "39",
+ "3a",
+ "3b",
+ "3c",
+ "3d",
+ "3e",
+ "40",
+ "41",
+ "42",
+ "43",
+ "44",
+ "45",
+ "50",
+ "51",
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "57",
+ "58",
+ "59",
+ "5a",
+ "5b",
+ "60ff",
+ "61ffff",
+ "62ffffff",
+ "63ffffffff",
+ "64ffffffffff",
+ "65ffffffffffff",
+ "66ffffffffffffff",
+ "67ffffffffffffffff",
+ "68ffffffffffffffffff",
+ "69ffffffffffffffffffff",
+ "6affffffffffffffffffffff",
+ "6bffffffffffffffffffffffff",
+ "6cffffffffffffffffffffffffff",
+ "6dffffffffffffffffffffffffffff",
+ "6effffffffffffffffffffffffffffff",
+ "6fffffffffffffffffffffffffffffffff",
+ "70ffffffffffffffffffffffffffffffffff",
+ "71ffffffffffffffffffffffffffffffffffff",
+ "72ffffffffffffffffffffffffffffffffffffff",
+ "73ffffffffffffffffffffffffffffffffffffffff",
+ "74ffffffffffffffffffffffffffffffffffffffffff",
+ "75ffffffffffffffffffffffffffffffffffffffffffff",
+ "76ffffffffffffffffffffffffffffffffffffffffffffff",
+ "77ffffffffffffffffffffffffffffffffffffffffffffffff",
+ "78ffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "79ffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7affffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "80",
+ "81",
+ "82",
+ "83",
+ "84",
+ "85",
+ "86",
+ "87",
+ "88",
+ "89",
+ "8a",
+ "8b",
+ "8c",
+ "8d",
+ "8e",
+ "8f",
+ "90",
+ "91",
+ "92",
+ "93",
+ "94",
+ "95",
+ "96",
+ "97",
+ "98",
+ "99",
+ "9a",
+ "9b",
+ "9c",
+ "9d",
+ "9e",
+ "9f",
+ "a0",
+ "a1",
+ "a2",
+ "a3",
+ "a4",
+ "f0",
+ "f1",
+ "f2",
+ "f3",
+ "f4",
+ "fa",
+ "fd",
+ "fe",
+ "ff"
+ };
+
+ vector<string> opcodes_lll {
+ "{ (asm STOP) }",
+ "{ (asm ADD) }",
+ "{ (asm MUL) }",
+ "{ (asm SUB) }",
+ "{ (asm DIV) }",
+ "{ (asm SDIV ) }",
+ "{ (asm MOD) }",
+ "{ (asm SMOD) }",
+ "{ (asm ADDMOD) }",
+ "{ (asm MULMOD) }",
+ "{ (asm EXP) }",
+ "{ (asm SIGNEXTEND) }",
+ "{ (asm LT) }",
+ "{ (asm GT) }",
+ "{ (asm SLT) }",
+ "{ (asm SGT) }",
+ "{ (asm EQ) }",
+ "{ (asm ISZERO) }",
+ "{ (asm AND) }",
+ "{ (asm OR) }",
+ "{ (asm XOR) }",
+ "{ (asm NOT) }",
+ "{ (asm BYTE) }",
+ "{ (asm KECCAK256) }",
+ "{ (asm ADDRESS) }",
+ "{ (asm BALANCE) }",
+ "{ (asm ORIGIN) }",
+ "{ (asm CALLER) }",
+ "{ (asm CALLVALUE) }",
+ "{ (asm CALLDATALOAD) }",
+ "{ (asm CALLDATASIZE) }",
+ "{ (asm CALLDATACOPY) }",
+ "{ (asm CODESIZE) }",
+ "{ (asm CODECOPY) }",
+ "{ (asm GASPRICE) }",
+ "{ (asm EXTCODESIZE)}",
+ "{ (asm EXTCODECOPY) }",
+ "{ (asm RETURNDATASIZE) }",
+ "{ (asm RETURNDATACOPY) }",
+ "{ (asm BLOCKHASH) }",
+ "{ (asm COINBASE) }",
+ "{ (asm TIMESTAMP) }",
+ "{ (asm NUMBER) }",
+ "{ (asm DIFFICULTY) }",
+ "{ (asm GASLIMIT) }",
+ "{ (asm POP) }",
+ "{ (asm MLOAD) }",
+ "{ (asm MSTORE) }",
+ "{ (asm MSTORE8) }",
+ "{ (asm SLOAD) }",
+ "{ (asm SSTORE) }",
+ "{ (asm JUMP ) }",
+ "{ (asm JUMPI ) }",
+ "{ (asm PC) }",
+ "{ (asm MSIZE) }",
+ "{ (asm GAS) }",
+ "{ (asm JUMPDEST) }",
+ "{ (asm 0xff) }",
+ "{ (asm 0xffff) }",
+ "{ (asm 0xffffff) }",
+ "{ (asm 0xffffffff) }",
+ "{ (asm 0xffffffffff) }",
+ "{ (asm 0xffffffffffff) }",
+ "{ (asm 0xffffffffffffff) }",
+ "{ (asm 0xffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) }",
+ "{ (asm DUP1) }",
+ "{ (asm DUP2) }",
+ "{ (asm DUP3) }",
+ "{ (asm DUP4) }",
+ "{ (asm DUP5) }",
+ "{ (asm DUP6) }",
+ "{ (asm DUP7) }",
+ "{ (asm DUP8) }",
+ "{ (asm DUP9) }",
+ "{ (asm DUP10) }",
+ "{ (asm DUP11) }",
+ "{ (asm DUP12) }",
+ "{ (asm DUP13) }",
+ "{ (asm DUP14) }",
+ "{ (asm DUP15) }",
+ "{ (asm DUP16) }",
+ "{ (asm SWAP1) }",
+ "{ (asm SWAP2) }",
+ "{ (asm SWAP3) }",
+ "{ (asm SWAP4) }",
+ "{ (asm SWAP5) }",
+ "{ (asm SWAP6) }",
+ "{ (asm SWAP7) }",
+ "{ (asm SWAP8) }",
+ "{ (asm SWAP9) }",
+ "{ (asm SWAP10) }",
+ "{ (asm SWAP11) }",
+ "{ (asm SWAP12) }",
+ "{ (asm SWAP13) }",
+ "{ (asm SWAP14) }",
+ "{ (asm SWAP15) }",
+ "{ (asm SWAP16) }",
+ "{ (asm LOG0) }",
+ "{ (asm LOG1) }",
+ "{ (asm LOG2) }",
+ "{ (asm LOG3) }",
+ "{ (asm LOG4) }",
+ "{ (asm CREATE) }",
+ "{ (asm CALL) }",
+ "{ (asm CALLCODE) }",
+ "{ (asm RETURN) }",
+ "{ (asm DELEGATECALL) }",
+ "{ (asm STATICCALL) }",
+ "{ (asm REVERT) }",
+ "{ (asm INVALID) }",
+ "{ (asm SELFDESTRUCT) }"
+ };
+
+ for (size_t i = 0; i < opcodes_bytecode.size(); i++) {
+ vector<string> errors;
+ bytes code = eth::compileLLL(opcodes_lll[i], false, &errors);
+
+ BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]);
+
+ BOOST_CHECK_EQUAL(toHex(code), opcodes_bytecode[i]);
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp
index 3bdc40a0..ea9703ea 100644
--- a/test/libsolidity/AnalysisFramework.cpp
+++ b/test/libsolidity/AnalysisFramework.cpp
@@ -81,7 +81,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
}
}
- return make_pair(&m_compiler.ast(), firstError);
+ return make_pair(&m_compiler.ast(""), firstError);
}
SourceUnit const* AnalysisFramework::parseAndAnalyse(string const& _source)
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index 56ac8cf5..358d3c72 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(location_test)
shared_ptr<string const> n = make_shared<string>("");
AssemblyItems items = compileContract(sourceCode);
vector<SourceLocation> locations =
- vector<SourceLocation>(18, SourceLocation(2, 75, n)) +
+ vector<SourceLocation>(24, SourceLocation(2, 75, n)) +
vector<SourceLocation>(32, SourceLocation(20, 72, n)) +
vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
vector<SourceLocation>(2, SourceLocation(58, 67, n)) +
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp
index c2886f5b..86e8201b 100644
--- a/test/libsolidity/GasMeter.cpp
+++ b/test/libsolidity/GasMeter.cpp
@@ -51,8 +51,8 @@ public:
m_compiler.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
- AssemblyItems const* items = m_compiler.runtimeAssemblyItems("");
- ASTNode const& sourceUnit = m_compiler.ast();
+ 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})),
@@ -64,13 +64,13 @@ public:
{
compileAndRun(_sourceCode);
auto state = make_shared<KnownState>();
- PathGasMeter meter(*m_compiler.assemblyItems());
+ PathGasMeter meter(*m_compiler.assemblyItems(m_compiler.lastContractName()));
GasMeter::GasConsumption gas = meter.estimateMax(0, state);
- u256 bytecodeSize(m_compiler.runtimeObject().bytecode.size());
+ u256 bytecodeSize(m_compiler.runtimeObject(m_compiler.lastContractName()).bytecode.size());
// costs for deployment
gas += bytecodeSize * GasCosts::createDataGas;
// costs for transaction
- gas += gasForTransaction(m_compiler.object().bytecode, true);
+ gas += gasForTransaction(m_compiler.object(m_compiler.lastContractName()).bytecode, true);
BOOST_REQUIRE(!gas.isInfinite);
BOOST_CHECK(gas.value == m_gasUsed);
@@ -91,7 +91,7 @@ public:
}
gas += GasEstimator::functionalEstimation(
- *m_compiler.runtimeAssemblyItems(),
+ *m_compiler.runtimeAssemblyItems(m_compiler.lastContractName()),
_sig
);
BOOST_REQUIRE(!gas.isInfinite);
@@ -135,7 +135,7 @@ BOOST_AUTO_TEST_CASE(non_overlapping_filtered_costs)
if (first->first->location().intersects(second->first->location()))
{
BOOST_CHECK_MESSAGE(false, "Source locations should not overlap!");
- auto scannerFromSource = [&](string const&) -> Scanner const& { return m_compiler.scanner(); };
+ auto scannerFromSource = [&](string const& _sourceName) -> Scanner const& { return m_compiler.scanner(_sourceName); };
SourceReferenceFormatter::printSourceLocation(cout, &first->first->location(), scannerFromSource);
SourceReferenceFormatter::printSourceLocation(cout, &second->first->location(), scannerFromSource);
}
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index 42f7525f..33962730 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -46,7 +46,7 @@ public:
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code);
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
- Json::Value generatedInterface = m_compilerStack.contractABI("");
+ Json::Value generatedInterface = m_compilerStack.contractABI(m_compilerStack.lastContractName());
Json::Value expectedInterface;
BOOST_REQUIRE(m_reader.parse(_expectedInterfaceString, expectedInterface));
BOOST_CHECK_MESSAGE(
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 35916ec7..9a837113 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -2899,6 +2899,25 @@ BOOST_AUTO_TEST_CASE(default_fallback_throws)
ABI_CHECK(callContractFunction("f()"), encodeArgs(0));
}
+BOOST_AUTO_TEST_CASE(short_data_calls_fallback)
+{
+ char const* sourceCode = R"(
+ contract A {
+ uint public x;
+ // Signature is d88e0b00
+ function fow() { x = 3; }
+ function () { x = 2; }
+ }
+ )";
+ compileAndRun(sourceCode);
+ // should call fallback
+ sendMessage(asBytes("\xd8\x8e\x0b"), false, 0);
+ ABI_CHECK(callContractFunction("x()"), encodeArgs(2));
+ // should call function
+ sendMessage(asBytes(string("\xd8\x8e\x0b") + string(1, 0)), false, 0);
+ ABI_CHECK(callContractFunction("x()"), encodeArgs(3));
+}
+
BOOST_AUTO_TEST_CASE(event)
{
char const* sourceCode = R"(
@@ -7309,6 +7328,30 @@ BOOST_AUTO_TEST_CASE(create_memory_array)
ABI_CHECK(callContractFunction("f()"), encodeArgs(string("A"), u256(8), u256(4), string("B")));
}
+BOOST_AUTO_TEST_CASE(create_memory_array_allocation_size)
+{
+ // Check allocation size of byte array. Should be 32 plus length rounded up to next
+ // multiple of 32
+ char const* sourceCode = R"(
+ contract C {
+ function f() pure returns (uint d1, uint d2, uint d3) {
+ bytes memory b1 = new bytes(31);
+ bytes memory b2 = new bytes(32);
+ bytes memory b3 = new bytes(256);
+ bytes memory b4 = new bytes(31);
+ assembly {
+ d1 := sub(b2, b1)
+ d2 := sub(b3, b2)
+ d3 := sub(b4, b3)
+ }
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(0x40, 0x40, 0x20 + 256));
+}
+
+
BOOST_AUTO_TEST_CASE(memory_arrays_of_various_sizes)
{
// Computes binomial coefficients the chinese way
@@ -10176,6 +10219,307 @@ BOOST_AUTO_TEST_CASE(address_overload_resolution)
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(5)));
}
+BOOST_AUTO_TEST_CASE(snark)
+{
+ char const* sourceCode = R"(
+ library Pairing {
+ struct G1Point {
+ uint X;
+ uint Y;
+ }
+ // Encoding of field elements is: X[0] * z + X[1]
+ struct G2Point {
+ uint[2] X;
+ uint[2] Y;
+ }
+
+ /// @return the generator of G1
+ function P1() internal returns (G1Point) {
+ return G1Point(1, 2);
+ }
+
+ /// @return the generator of G2
+ function P2() internal returns (G2Point) {
+ return G2Point(
+ [11559732032986387107991004021392285783925812861821192530917403151452391805634,
+ 10857046999023057135944570762232829481370756359578518086990519993285655852781],
+ [4082367875863433681332203403145435568316851327593401208105741076214120093531,
+ 8495653923123431417604973247489272438418190587263600148770280649306958101930]
+ );
+ }
+
+ /// @return the negation of p, i.e. p.add(p.negate()) should be zero.
+ function negate(G1Point p) internal returns (G1Point) {
+ // The prime q in the base field F_q for G1
+ uint q = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
+ if (p.X == 0 && p.Y == 0)
+ return G1Point(0, 0);
+ return G1Point(p.X, q - (p.Y % q));
+ }
+
+ /// @return the sum of two points of G1
+ function add(G1Point p1, G1Point p2) internal returns (G1Point r) {
+ uint[4] memory input;
+ input[0] = p1.X;
+ input[1] = p1.Y;
+ input[2] = p2.X;
+ input[3] = p2.Y;
+ bool success;
+ assembly {
+ success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60)
+ // Use "invalid" to make gas estimation work
+ switch success case 0 { invalid() }
+ }
+ require(success);
+ }
+
+ /// @return the product of a point on G1 and a scalar, i.e.
+ /// p == p.mul(1) and p.add(p) == p.mul(2) for all points p.
+ function mul(G1Point p, uint s) internal returns (G1Point r) {
+ uint[3] memory input;
+ input[0] = p.X;
+ input[1] = p.Y;
+ input[2] = s;
+ bool success;
+ assembly {
+ success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60)
+ // Use "invalid" to make gas estimation work
+ switch success case 0 { invalid() }
+ }
+ require(success);
+ }
+
+ /// @return the result of computing the pairing check
+ /// e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1
+ /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should
+ /// return true.
+ function pairing(G1Point[] p1, G2Point[] p2) internal returns (bool) {
+ require(p1.length == p2.length);
+ uint elements = p1.length;
+ uint inputSize = p1.length * 6;
+ uint[] memory input = new uint[](inputSize);
+ for (uint i = 0; i < elements; i++)
+ {
+ input[i * 6 + 0] = p1[i].X;
+ input[i * 6 + 1] = p1[i].Y;
+ input[i * 6 + 2] = p2[i].X[0];
+ input[i * 6 + 3] = p2[i].X[1];
+ input[i * 6 + 4] = p2[i].Y[0];
+ input[i * 6 + 5] = p2[i].Y[1];
+ }
+ uint[1] memory out;
+ bool success;
+ assembly {
+ success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
+ // Use "invalid" to make gas estimation work
+ switch success case 0 { invalid() }
+ }
+ require(success);
+ return out[0] != 0;
+ }
+ function pairingProd2(G1Point a1, G2Point a2, G1Point b1, G2Point b2) internal returns (bool) {
+ G1Point[] memory p1 = new G1Point[](2);
+ G2Point[] memory p2 = new G2Point[](2);
+ p1[0] = a1;
+ p1[1] = b1;
+ p2[0] = a2;
+ p2[1] = b2;
+ return pairing(p1, p2);
+ }
+ function pairingProd3(
+ G1Point a1, G2Point a2,
+ G1Point b1, G2Point b2,
+ G1Point c1, G2Point c2
+ ) internal returns (bool) {
+ G1Point[] memory p1 = new G1Point[](3);
+ G2Point[] memory p2 = new G2Point[](3);
+ p1[0] = a1;
+ p1[1] = b1;
+ p1[2] = c1;
+ p2[0] = a2;
+ p2[1] = b2;
+ p2[2] = c2;
+ return pairing(p1, p2);
+ }
+ function pairingProd4(
+ G1Point a1, G2Point a2,
+ G1Point b1, G2Point b2,
+ G1Point c1, G2Point c2,
+ G1Point d1, G2Point d2
+ ) internal returns (bool) {
+ G1Point[] memory p1 = new G1Point[](4);
+ G2Point[] memory p2 = new G2Point[](4);
+ p1[0] = a1;
+ p1[1] = b1;
+ p1[2] = c1;
+ p1[3] = d1;
+ p2[0] = a2;
+ p2[1] = b2;
+ p2[2] = c2;
+ p2[3] = d2;
+ return pairing(p1, p2);
+ }
+ }
+
+ contract Test {
+ using Pairing for *;
+ struct VerifyingKey {
+ Pairing.G2Point A;
+ Pairing.G1Point B;
+ Pairing.G2Point C;
+ Pairing.G2Point gamma;
+ Pairing.G1Point gammaBeta1;
+ Pairing.G2Point gammaBeta2;
+ Pairing.G2Point Z;
+ Pairing.G1Point[] IC;
+ }
+ struct Proof {
+ Pairing.G1Point A;
+ Pairing.G1Point A_p;
+ Pairing.G2Point B;
+ Pairing.G1Point B_p;
+ Pairing.G1Point C;
+ Pairing.G1Point C_p;
+ Pairing.G1Point K;
+ Pairing.G1Point H;
+ }
+ function f() returns (bool) {
+ Pairing.G1Point memory p1;
+ Pairing.G1Point memory p2;
+ p1.X = 1; p1.Y = 2;
+ p2.X = 1; p2.Y = 2;
+ var explict_sum = Pairing.add(p1, p2);
+ var scalar_prod = Pairing.mul(p1, 2);
+ return (explict_sum.X == scalar_prod.X &&
+ explict_sum.Y == scalar_prod.Y);
+ }
+ function g() returns (bool) {
+ Pairing.G1Point memory x = Pairing.add(Pairing.P1(), Pairing.negate(Pairing.P1()));
+ // should be zero
+ return (x.X == 0 && x.Y == 0);
+ }
+ function testMul() returns (bool) {
+ Pairing.G1Point memory p;
+ // @TODO The points here are reported to be not well-formed
+ p.X = 14125296762497065001182820090155008161146766663259912659363835465243039841726;
+ p.Y = 16229134936871442251132173501211935676986397196799085184804749187146857848057;
+ p = Pairing.mul(p, 13986731495506593864492662381614386532349950841221768152838255933892789078521);
+ return
+ p.X == 18256332256630856740336504687838346961237861778318632856900758565550522381207 &&
+ p.Y == 6976682127058094634733239494758371323697222088503263230319702770853579280803;
+ }
+ function pair() returns (bool) {
+ Pairing.G2Point memory fiveTimesP2 = Pairing.G2Point(
+ [4540444681147253467785307942530223364530218361853237193970751657229138047649, 20954117799226682825035885491234530437475518021362091509513177301640194298072],
+ [11631839690097995216017572651900167465857396346217730511548857041925508482915, 21508930868448350162258892668132814424284302804699005394342512102884055673846]
+ );
+ // The prime p in the base field F_p for G1
+ uint p = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
+ Pairing.G1Point[] memory g1points = new Pairing.G1Point[](2);
+ Pairing.G2Point[] memory g2points = new Pairing.G2Point[](2);
+ // check e(5 P1, P2)e(-P1, 5 P2) == 1
+ g1points[0] = Pairing.P1().mul(5);
+ g1points[1] = Pairing.P1().negate();
+ g2points[0] = Pairing.P2();
+ g2points[1] = fiveTimesP2;
+ if (!Pairing.pairing(g1points, g2points))
+ return false;
+ // check e(P1, P2)e(-P1, P2) == 1
+ g1points[0] = Pairing.P1();
+ g1points[1] = Pairing.P1();
+ g1points[1].Y = p - g1points[1].Y;
+ g2points[0] = Pairing.P2();
+ g2points[1] = Pairing.P2();
+ if (!Pairing.pairing(g1points, g2points))
+ return false;
+ return true;
+ }
+ function verifyingKey() internal returns (VerifyingKey vk) {
+ vk.A = Pairing.G2Point([0x209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7, 0x04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678], [0x2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d, 0x120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550]);
+ vk.B = Pairing.G1Point(0x2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc02, 0x03d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db84);
+ vk.C = Pairing.G2Point([0x2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb, 0x01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb3], [0x14a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713, 0x178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee24590]);
+ vk.gamma = Pairing.G2Point([0x25f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb1, 0x22acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d], [0x065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf68, 0x06d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb]);
+ vk.gammaBeta1 = Pairing.G1Point(0x15794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f21, 0x14db745c6780e9df549864cec19c2daf4531f6ec0c89cc1c7436cc4d8d300c6d);
+ vk.gammaBeta2 = Pairing.G2Point([0x1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e, 0x283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39], [0x140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e, 0x0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd4]);
+ vk.Z = Pairing.G2Point([0x217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac29, 0x0a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c], [0x26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a9855, 0x2fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d7]);
+ vk.IC = new Pairing.G1Point[](10);
+ vk.IC[0] = Pairing.G1Point(0x0aee46a7ea6e80a3675026dfa84019deee2a2dedb1bbe11d7fe124cb3efb4b5a, 0x044747b6e9176e13ede3a4dfd0d33ccca6321b9acd23bf3683a60adc0366ebaf);
+ vk.IC[1] = Pairing.G1Point(0x1e39e9f0f91fa7ff8047ffd90de08785777fe61c0e3434e728fce4cf35047ddc, 0x2e0b64d75ebfa86d7f8f8e08abbe2e7ae6e0a1c0b34d028f19fa56e9450527cb);
+ vk.IC[2] = Pairing.G1Point(0x1c36e713d4d54e3a9644dffca1fc524be4868f66572516025a61ca542539d43f, 0x042dcc4525b82dfb242b09cb21909d5c22643dcdbe98c4d082cc2877e96b24db);
+ vk.IC[3] = Pairing.G1Point(0x17d5d09b4146424bff7e6fb01487c477bbfcd0cdbbc92d5d6457aae0b6717cc5, 0x02b5636903efbf46db9235bbe74045d21c138897fda32e079040db1a16c1a7a1);
+ vk.IC[4] = Pairing.G1Point(0x0f103f14a584d4203c27c26155b2c955f8dfa816980b24ba824e1972d6486a5d, 0x0c4165133b9f5be17c804203af781bcf168da7386620479f9b885ecbcd27b17b);
+ vk.IC[5] = Pairing.G1Point(0x232063b584fb76c8d07995bee3a38fa7565405f3549c6a918ddaa90ab971e7f8, 0x2ac9b135a81d96425c92d02296322ad56ffb16299633233e4880f95aafa7fda7);
+ vk.IC[6] = Pairing.G1Point(0x09b54f111d3b2d1b2fe1ae9669b3db3d7bf93b70f00647e65c849275de6dc7fe, 0x18b2e77c63a3e400d6d1f1fbc6e1a1167bbca603d34d03edea231eb0ab7b14b4);
+ vk.IC[7] = Pairing.G1Point(0x0c54b42137b67cc268cbb53ac62b00ecead23984092b494a88befe58445a244a, 0x18e3723d37fae9262d58b548a0575f59d9c3266db7afb4d5739555837f6b8b3e);
+ vk.IC[8] = Pairing.G1Point(0x0a6de0e2240aa253f46ce0da883b61976e3588146e01c9d8976548c145fe6e4a, 0x04fbaa3a4aed4bb77f30ebb07a3ec1c7d77a7f2edd75636babfeff97b1ea686e);
+ vk.IC[9] = Pairing.G1Point(0x111e2e2a5f8828f80ddad08f9f74db56dac1cc16c1cb278036f79a84cf7a116f, 0x1d7d62e192b219b9808faa906c5ced871788f6339e8d91b83ac1343e20a16b30);
+ }
+ function verify(uint[] input, Proof proof) internal returns (uint) {
+ VerifyingKey memory vk = verifyingKey();
+ require(input.length + 1 == vk.IC.length);
+ // Compute the linear combination vk_x
+ Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0);
+ for (uint i = 0; i < input.length; i++)
+ vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i]));
+ vk_x = Pairing.add(vk_x, vk.IC[0]);
+ if (!Pairing.pairingProd2(proof.A, vk.A, Pairing.negate(proof.A_p), Pairing.P2())) return 1;
+ if (!Pairing.pairingProd2(vk.B, proof.B, Pairing.negate(proof.B_p), Pairing.P2())) return 2;
+ if (!Pairing.pairingProd2(proof.C, vk.C, Pairing.negate(proof.C_p), Pairing.P2())) return 3;
+ if (!Pairing.pairingProd3(
+ proof.K, vk.gamma,
+ Pairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), vk.gammaBeta2,
+ Pairing.negate(vk.gammaBeta1), proof.B
+ )) return 4;
+ if (!Pairing.pairingProd3(
+ Pairing.add(vk_x, proof.A), proof.B,
+ Pairing.negate(proof.H), vk.Z,
+ Pairing.negate(proof.C), Pairing.P2()
+ )) return 5;
+ return 0;
+ }
+ event Verified(string);
+ function verifyTx() returns (bool) {
+ uint[] memory input = new uint[](9);
+ Proof memory proof;
+ proof.A = Pairing.G1Point(12873740738727497448187997291915224677121726020054032516825496230827252793177, 21804419174137094775122804775419507726154084057848719988004616848382402162497);
+ proof.A_p = Pairing.G1Point(7742452358972543465462254569134860944739929848367563713587808717088650354556, 7324522103398787664095385319014038380128814213034709026832529060148225837366);
+ proof.B = Pairing.G2Point(
+ [8176651290984905087450403379100573157708110416512446269839297438960217797614, 15588556568726919713003060429893850972163943674590384915350025440408631945055],
+ [15347511022514187557142999444367533883366476794364262773195059233657571533367, 4265071979090628150845437155927259896060451682253086069461962693761322642015]);
+ proof.B_p = Pairing.G1Point(2979746655438963305714517285593753729335852012083057917022078236006592638393, 6470627481646078059765266161088786576504622012540639992486470834383274712950);
+ proof.C = Pairing.G1Point(6851077925310461602867742977619883934042581405263014789956638244065803308498, 10336382210592135525880811046708757754106524561907815205241508542912494488506);
+ proof.C_p = Pairing.G1Point(12491625890066296859584468664467427202390981822868257437245835716136010795448, 13818492518017455361318553880921248537817650587494176379915981090396574171686);
+ proof.H = Pairing.G1Point(12091046215835229523641173286701717671667447745509192321596954139357866668225, 14446807589950902476683545679847436767890904443411534435294953056557941441758);
+ proof.K = Pairing.G1Point(21341087976609916409401737322664290631992568431163400450267978471171152600502, 2942165230690572858696920423896381470344658299915828986338281196715687693170);
+ input[0] = 13986731495506593864492662381614386532349950841221768152838255933892789078521;
+ input[1] = 622860516154313070522697309645122400675542217310916019527100517240519630053;
+ input[2] = 11094488463398718754251685950409355128550342438297986977413505294941943071569;
+ input[3] = 6627643779954497813586310325594578844876646808666478625705401786271515864467;
+ input[4] = 2957286918163151606545409668133310005545945782087581890025685458369200827463;
+ input[5] = 1384290496819542862903939282897996566903332587607290986044945365745128311081;
+ input[6] = 5613571677741714971687805233468747950848449704454346829971683826953541367271;
+ input[7] = 9643208548031422463313148630985736896287522941726746581856185889848792022807;
+ input[8] = 18066496933330839731877828156604;
+ if (verify(input, proof) == 0) {
+ Verified("Transaction successfully verified.");
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ }
+ )";
+ compileAndRun(sourceCode, 0, "Pairing");
+ compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Pairing", m_contractAddress}});
+ // Disabled because the point seems to be not well-formed, we need to find another example.
+ //BOOST_CHECK(callContractFunction("testMul()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("g()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("pair()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("verifyTx()") == encodeArgs(true));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h
index 342d0875..b0daaba9 100644
--- a/test/libsolidity/SolidityExecutionFramework.h
+++ b/test/libsolidity/SolidityExecutionFramework.h
@@ -69,7 +69,7 @@ public:
);
BOOST_ERROR("Compiling contract failed");
}
- eth::LinkerObject obj = m_compiler.object(_contractName);
+ eth::LinkerObject obj = m_compiler.object(_contractName.empty() ? m_compiler.lastContractName() : _contractName);
BOOST_REQUIRE(obj.linkReferences.empty());
sendMessage(obj.bytecode + _arguments, true, _value);
return m_output;
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 903e7308..e5990e9b 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -4783,6 +4783,16 @@ BOOST_AUTO_TEST_CASE(warn_about_callcode)
}
)";
CHECK_WARNING(text, "\"callcode\" has been deprecated in favour of \"delegatecall\"");
+ text = R"(
+ pragma experimental "v0.5.0";
+ contract test {
+ function f() pure public {
+ var x = address(0x12).callcode;
+ x;
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "\"callcode\" has been deprecated in favour of \"delegatecall\"");
}
BOOST_AUTO_TEST_CASE(no_warn_about_callcode_as_function)
@@ -5537,7 +5547,7 @@ BOOST_AUTO_TEST_CASE(invalid_mobile_type)
}
}
)";
- CHECK_ERROR(text, TypeError, "Invalid mobile type.");
+ CHECK_ERROR(text, TypeError, "Invalid rational number.");
}
BOOST_AUTO_TEST_CASE(warns_msg_value_in_non_payable_public_function)
@@ -5879,6 +5889,28 @@ BOOST_AUTO_TEST_CASE(interface_function_bodies)
CHECK_ERROR(text, TypeError, "Functions in interfaces cannot have an implementation");
}
+BOOST_AUTO_TEST_CASE(interface_function_external)
+{
+ char const* text = R"(
+ pragma experimental "v0.5.0";
+ interface I {
+ function f() external;
+ }
+ )";
+ success(text);
+}
+
+BOOST_AUTO_TEST_CASE(interface_function_public)
+{
+ char const* text = R"(
+ pragma experimental "v0.5.0";
+ interface I {
+ function f() public;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Functions in interfaces must be declared external.");
+}
+
BOOST_AUTO_TEST_CASE(interface_function_internal)
{
char const* text = R"(
@@ -7074,6 +7106,53 @@ BOOST_AUTO_TEST_CASE(non_external_fallback)
CHECK_ERROR(text, TypeError, "Fallback function must be defined as \"external\".");
}
+BOOST_AUTO_TEST_CASE(invalid_literal_in_tuple)
+{
+ char const* text = R"(
+ contract C {
+ function f() pure public {
+ uint x;
+ (x, ) = (1E111);
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "is not implicitly convertible to expected type");
+ text = R"(
+ contract C {
+ function f() pure public {
+ uint x;
+ (x, ) = (1, 1E111);
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Invalid rational number.");
+ text = R"(
+ contract C {
+ function f() pure public {
+ uint x;
+ (x, ) = (1E111, 1);
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Invalid rational number.");
+ text = R"(
+ contract C {
+ function f() pure public {
+ (2**270, 1);
+ }
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Invalid rational number.");
+ text = R"(
+ contract C {
+ function f() pure public {
+ ((2**270) / 2**100, 1);
+ }
+ }
+ )";
+ CHECK_SUCCESS(text);
+}
+
BOOST_AUTO_TEST_CASE(warn_about_sha3)
{
char const* text = R"(
@@ -7168,6 +7247,12 @@ BOOST_AUTO_TEST_CASE(array_length_invalid_expression)
}
)";
CHECK_ERROR(text, TypeError, "Invalid literal value.");
+ text = R"(
+ contract C {
+ uint[3/0] ids;
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Operator / not compatible with types int_const 3 and int_const 0");
}
BOOST_AUTO_TEST_CASE(no_address_members_on_contract)
diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
index d83773bc..fb09451f 100644
--- a/test/libsolidity/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -51,9 +51,9 @@ public:
Json::Value generatedDocumentation;
if (_userDocumentation)
- generatedDocumentation = m_compilerStack.natspecUser("");
+ generatedDocumentation = m_compilerStack.natspecUser(m_compilerStack.lastContractName());
else
- generatedDocumentation = m_compilerStack.natspecDev("");
+ generatedDocumentation = m_compilerStack.natspecDev(m_compilerStack.lastContractName());
Json::Value expectedDocumentation;
m_reader.parse(_expectedDocumentationString, expectedDocumentation);
BOOST_CHECK_MESSAGE(
diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp
index 80241519..6353ae8a 100644
--- a/test/libsolidity/ViewPureChecker.cpp
+++ b/test/libsolidity/ViewPureChecker.cpp
@@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(assembly)
assembly { x := 7 }
}
function g() view public {
- assembly { for {} 1 { pop(sload(0)) } { } }
+ assembly { for {} 1 { pop(sload(0)) } { } pop(gas) }
}
function h() view public {
assembly { function g() { pop(blockhash(20)) } }
@@ -357,6 +357,9 @@ BOOST_AUTO_TEST_CASE(assembly)
function j() public {
assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }
}
+ function k() public {
+ assembly { pop(call(gas, 1, 2, 3, 4, 5, 6)) }
+ }
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
@@ -367,7 +370,7 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
string text = R"(
contract C {
function i() view public {
- assembly { pop(staticcall(0, 1, 2, 3, 4, 5)) }
+ assembly { pop(staticcall(gas, 1, 2, 3, 4, 5)) }
}
}
)";