mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'whizz' of https://github.com/ethereum/cpp-ethereum into client_ref
Conflicts: libethereum/Client.cpp libevm/ExtVMFace.h
This commit is contained in:
commit
8261052185
@ -23,6 +23,7 @@
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <libethcore/EthashAux.h>
|
||||
#include <libethereum/Client.h>
|
||||
#include <liblll/Compiler.h>
|
||||
#include <libevm/VMFactory.h>
|
||||
@ -63,11 +64,17 @@ void connectClients(Client& c1, Client& c2)
|
||||
void mine(State& s, BlockChain const& _bc)
|
||||
{
|
||||
s.commitToMine(_bc);
|
||||
GenericFarm<ProofOfWork> f;
|
||||
GenericFarm<EthashProofOfWork> f;
|
||||
bool completed = false;
|
||||
f.onSolutionFound([&](ProofOfWork::Solution sol)
|
||||
Ethash::BlockHeader header(s.info);
|
||||
f.onSolutionFound([&](EthashProofOfWork::Solution sol)
|
||||
{
|
||||
return completed = s.completeMine<ProofOfWork>(sol);
|
||||
header.m_mixHash = sol.mixHash;
|
||||
header.m_nonce = sol.nonce;
|
||||
RLPStream ret;
|
||||
header.streamRLP(ret);
|
||||
s.sealBlock(ret);
|
||||
return true;
|
||||
});
|
||||
f.setWork(s.info());
|
||||
f.startCPU();
|
||||
@ -77,11 +84,11 @@ void mine(State& s, BlockChain const& _bc)
|
||||
|
||||
void mine(BlockInfo& _bi)
|
||||
{
|
||||
GenericFarm<ProofOfWork> f;
|
||||
GenericFarm<EthashProofOfWork> f;
|
||||
bool completed = false;
|
||||
f.onSolutionFound([&](ProofOfWork::Solution sol)
|
||||
f.onSolutionFound([&](EthashProofOfWork::Solution sol)
|
||||
{
|
||||
ProofOfWork::assignResult(sol, _bi);
|
||||
_bi.proof = sol;
|
||||
return completed = true;
|
||||
});
|
||||
f.setWork(_bi);
|
||||
@ -151,12 +158,12 @@ void ImportTest::importEnv(json_spirit::mObject& _o)
|
||||
assert(_o.count("currentCoinbase") > 0);
|
||||
assert(_o.count("currentNumber") > 0);
|
||||
|
||||
m_environment.currentBlock.parentHash = h256(_o["previousHash"].get_str());
|
||||
m_environment.currentBlock.parentHash() = h256(_o["previousHash"].get_str());
|
||||
m_environment.currentBlock.number = toInt(_o["currentNumber"]);
|
||||
m_environment.currentBlock.gasLimit = toInt(_o["currentGasLimit"]);
|
||||
m_environment.currentBlock.difficulty = toInt(_o["currentDifficulty"]);
|
||||
m_environment.currentBlock.timestamp = toInt(_o["currentTimestamp"]);
|
||||
m_environment.currentBlock.coinbaseAddress = Address(_o["currentCoinbase"].get_str());
|
||||
m_environment.currentBlock.timestamp() = toInt(_o["currentTimestamp"]);
|
||||
m_environment.currentBlock.coinbaseAddress() = Address(_o["currentCoinbase"].get_str());
|
||||
|
||||
m_statePre.m_previousBlock = m_environment.previousBlock;
|
||||
m_statePre.m_currentBlock = m_environment.currentBlock;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <tuple>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <libdevcore/Hash.h>
|
||||
#include <libsolidity/Exceptions.h>
|
||||
#include <test/libsolidity/solidityExecutionFramework.h>
|
||||
|
||||
using namespace std;
|
||||
@ -1187,7 +1188,7 @@ BOOST_AUTO_TEST_CASE(now)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" function someInfo() returns (bool success) {\n"
|
||||
" return block.timestamp == now && now > 0;\n"
|
||||
" return block.timestamp() == now && now > 0;\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
compileAndRun(sourceCode);
|
||||
@ -4657,6 +4658,32 @@ BOOST_AUTO_TEST_CASE(bytes_memory_index_access)
|
||||
) == encodeArgs(u256(data.size()), string("d")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(dev_title_at_function_error)
|
||||
{
|
||||
char const* sourceCode = " /// @author Lefteris\n"
|
||||
" /// @title Just a test contract\n"
|
||||
"contract test {\n"
|
||||
" /// @dev Mul function\n"
|
||||
" /// @title I really should not be here\n"
|
||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||
"}\n";
|
||||
|
||||
compileRequireThrow<DocstringParsingError>(sourceCode);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" /// @dev Multiplies a number by 7 and adds second parameter\n"
|
||||
" /// @param a Documentation for the first parameter\n"
|
||||
" /// @param not_existing Documentation for the second parameter\n"
|
||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||
"}\n";
|
||||
|
||||
compileRequireThrow<DocstringParsingError>(sourceCode);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(storage_array_ref)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -5033,6 +5060,44 @@ BOOST_AUTO_TEST_CASE(literal_strings)
|
||||
BOOST_CHECK(callContractFunction("empty()") == encodeDyn(string()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(initialise_string_constant)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
string public short = "abcdef";
|
||||
string public long = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
string longStr = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
|
||||
string shortStr = "abcdef";
|
||||
|
||||
BOOST_CHECK(callContractFunction("long()") == encodeDyn(longStr));
|
||||
BOOST_CHECK(callContractFunction("short()") == encodeDyn(shortStr));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
struct S { uint8 a; mapping(uint => uint) b; uint8 c; }
|
||||
S s;
|
||||
function f() returns (uint) {
|
||||
S memory x;
|
||||
if (x.a != 0 || x.c != 0) return 1;
|
||||
x.a = 4; x.c = 5;
|
||||
s = x;
|
||||
if (s.a != 4 || s.c != 5) return 2;
|
||||
x = S(2, 3);
|
||||
if (x.a != 2 || x.c != 3) return 3;
|
||||
x = s;
|
||||
if (s.a != 4 || s.c != 5) return 4;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
|
@ -2134,6 +2134,21 @@ BOOST_AUTO_TEST_CASE(invalid_integer_literal_exp)
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_with_mappings)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract Test {
|
||||
struct S { uint8 a; mapping(uint => uint) b; uint8 c; }
|
||||
S s;
|
||||
function f() {
|
||||
S memory x;
|
||||
x.b[1];
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "../TestHelper.h"
|
||||
#include <string>
|
||||
#include <json/json.h>
|
||||
#include <libsolidity/CompilerStack.h>
|
||||
#include <libsolidity/Exceptions.h>
|
||||
@ -38,9 +39,11 @@ class DocumentationChecker
|
||||
public:
|
||||
DocumentationChecker(): m_compilerStack(false) {}
|
||||
|
||||
void checkNatspec(std::string const& _code,
|
||||
std::string const& _expectedDocumentationString,
|
||||
bool _userDocumentation)
|
||||
void checkNatspec(
|
||||
std::string const& _code,
|
||||
std::string const& _expectedDocumentationString,
|
||||
bool _userDocumentation
|
||||
)
|
||||
{
|
||||
std::string generatedDocumentationString;
|
||||
ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse(_code), "Parsing failed");
|
||||
@ -53,9 +56,11 @@ public:
|
||||
m_reader.parse(generatedDocumentationString, generatedDocumentation);
|
||||
Json::Value expectedDocumentation;
|
||||
m_reader.parse(_expectedDocumentationString, expectedDocumentation);
|
||||
BOOST_CHECK_MESSAGE(expectedDocumentation == generatedDocumentation,
|
||||
"Expected " << _expectedDocumentationString <<
|
||||
"\n but got:\n" << generatedDocumentationString);
|
||||
BOOST_CHECK_MESSAGE(
|
||||
expectedDocumentation == generatedDocumentation,
|
||||
"Expected " << _expectedDocumentationString <<
|
||||
"\n but got:\n" << generatedDocumentationString
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -229,18 +234,6 @@ BOOST_AUTO_TEST_CASE(dev_multiple_params)
|
||||
checkNatspec(sourceCode, natspec, false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(dev_documenting_nonexistant_param)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" /// @dev Multiplies a number by 7 and adds second parameter\n"
|
||||
" /// @param a Documentation for the first parameter\n"
|
||||
" /// @param not_existing Documentation for the second parameter\n"
|
||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||
"}\n";
|
||||
|
||||
BOOST_CHECK_THROW(checkNatspec(sourceCode, "", false), DocstringParsingError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(dev_mutiline_param_description)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
@ -488,46 +481,48 @@ BOOST_AUTO_TEST_CASE(dev_author_at_function)
|
||||
checkNatspec(sourceCode, natspec, false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(dev_title_at_function_error)
|
||||
{
|
||||
char const* sourceCode = " /// @author Lefteris\n"
|
||||
" /// @title Just a test contract\n"
|
||||
"contract test {\n"
|
||||
" /// @dev Mul function\n"
|
||||
" /// @title I really should not be here\n"
|
||||
" function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n"
|
||||
"}\n";
|
||||
|
||||
BOOST_CHECK_THROW(checkNatspec(sourceCode, "", false), DocstringParsingError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_notice_without_tag)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" /// I do something awesome\n"
|
||||
" function mul(uint a) returns(uint d) { return a * 7; }\n"
|
||||
"}\n";
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
/// I do something awesome
|
||||
function mul(uint a) returns(uint d) { return a * 7; }
|
||||
}
|
||||
)";
|
||||
|
||||
char const* natspec = "{"
|
||||
"\"methods\":{"
|
||||
" \"mul(uint256)\":{ \"notice\": \"I do something awesome\"}"
|
||||
"}}";
|
||||
|
||||
char const* natspec = R"ABCDEF(
|
||||
{
|
||||
"methods" : {
|
||||
"mul(uint256)" : {
|
||||
"notice" : "I do something awesome"
|
||||
}
|
||||
}
|
||||
}
|
||||
)ABCDEF";
|
||||
|
||||
checkNatspec(sourceCode, natspec, true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(natspec_multiline_notice_without_tag)
|
||||
{
|
||||
char const* sourceCode = "contract test {\n"
|
||||
" /// I do something awesome\n"
|
||||
" /// which requires two lines to explain\n"
|
||||
" function mul(uint a) returns(uint d) { return a * 7; }\n"
|
||||
"}\n";
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
/// I do something awesome
|
||||
/// which requires two lines to explain
|
||||
function mul(uint a) returns(uint d) { return a * 7; }
|
||||
}
|
||||
)";
|
||||
|
||||
char const* natspec = "{"
|
||||
"\"methods\":{"
|
||||
" \"mul(uint256)\":{ \"notice\": \"I do something awesome which requires two lines to explain\"}"
|
||||
"}}";
|
||||
char const* natspec = R"ABCDEF(
|
||||
{
|
||||
"methods" : {
|
||||
"mul(uint256)" : {
|
||||
"notice" : "I do something awesome which requires two lines to explain"
|
||||
}
|
||||
}
|
||||
}
|
||||
)ABCDEF";
|
||||
|
||||
checkNatspec(sourceCode, natspec, true);
|
||||
}
|
||||
|
@ -89,11 +89,16 @@ contract multiowned {
|
||||
|
||||
// constructor is given number of sigs required to do protected "onlymanyowners" transactions
|
||||
// as well as the selection of addresses capable of confirming them.
|
||||
function multiowned() {
|
||||
m_required = 1;
|
||||
m_numOwners = 1;
|
||||
m_owners[m_numOwners] = uint(msg.sender);
|
||||
m_ownerIndex[uint(msg.sender)] = m_numOwners;
|
||||
function multiowned(address[] _owners, uint _required) {
|
||||
m_numOwners = _owners.length + 1;
|
||||
m_owners[1] = uint(msg.sender);
|
||||
m_ownerIndex[uint(msg.sender)] = 1;
|
||||
for (uint i = 0; i < _owners.length; ++i)
|
||||
{
|
||||
m_owners[2 + i] = uint(_owners[i]);
|
||||
m_ownerIndex[uint(_owners[i])] = 2 + i;
|
||||
}
|
||||
m_required = _required;
|
||||
}
|
||||
|
||||
// Revokes a prior confirmation of the given operation
|
||||
@ -122,6 +127,7 @@ contract multiowned {
|
||||
m_ownerIndex[uint(_to)] = ownerIndex;
|
||||
OwnerChanged(_from, _to);
|
||||
}
|
||||
|
||||
function addOwner(address _owner) onlymanyowners(sha3(msg.data, block.number)) external {
|
||||
if (isOwner(_owner)) return;
|
||||
|
||||
@ -346,15 +352,10 @@ contract Wallet is multisig, multiowned, daylimit {
|
||||
bytes data;
|
||||
}
|
||||
|
||||
// EVENTS
|
||||
|
||||
event Created(bytes32 indexed identifier);
|
||||
|
||||
// METHODS
|
||||
|
||||
// constructor - just pass on the owner arra to the multiowned.
|
||||
function Wallet(bytes32 identifier) {
|
||||
Created(identifier);
|
||||
// constructor - just pass on the owner array to the multiowned.
|
||||
function Wallet(address[] _owners, uint _required) multiowned(_owners, _required) {
|
||||
}
|
||||
|
||||
// kills the contract sending everything to `_to`.
|
||||
@ -423,7 +424,7 @@ static unique_ptr<bytes> s_compiledWallet;
|
||||
class WalletTestFramework: public ExecutionFramework
|
||||
{
|
||||
protected:
|
||||
void deployWallet(u256 const& _value = 0)
|
||||
void deployWallet(u256 const& _value = 0, vector<u256> const& _owners = vector<u256>{}, u256 _required = 1)
|
||||
{
|
||||
if (!s_compiledWallet)
|
||||
{
|
||||
@ -433,7 +434,8 @@ protected:
|
||||
ETH_TEST_REQUIRE_NO_THROW(m_compiler.compile(m_optimize, m_optimizeRuns), "Compiling contract failed");
|
||||
s_compiledWallet.reset(new bytes(m_compiler.getBytecode("Wallet")));
|
||||
}
|
||||
sendMessage(*s_compiledWallet, true, _value);
|
||||
bytes args = encodeArgs(u256(0x40), _required, u256(_owners.size()), _owners);
|
||||
sendMessage(*s_compiledWallet + args, true, _value);
|
||||
BOOST_REQUIRE(!m_output.empty());
|
||||
}
|
||||
};
|
||||
@ -506,6 +508,17 @@ BOOST_AUTO_TEST_CASE(remove_owner)
|
||||
BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x12 + i)) == encodeArgs(true));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(initial_owners)
|
||||
{
|
||||
deployWallet(200, vector<u256>{5, 6, 7}, 2);
|
||||
BOOST_CHECK(callContractFunction("m_numOwners()") == encodeArgs(u256(4)));
|
||||
BOOST_CHECK(callContractFunction("isOwner(address)", h256(m_sender, h256::AlignRight)) == encodeArgs(true));
|
||||
BOOST_CHECK(callContractFunction("isOwner(address)", u256(5)) == encodeArgs(true));
|
||||
BOOST_CHECK(callContractFunction("isOwner(address)", u256(6)) == encodeArgs(true));
|
||||
BOOST_CHECK(callContractFunction("isOwner(address)", u256(7)) == encodeArgs(true));
|
||||
BOOST_CHECK(callContractFunction("isOwner(address)", u256(8)) == encodeArgs(false));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multisig_value_transfer)
|
||||
{
|
||||
deployWallet(200);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <libethereum/State.h>
|
||||
#include <libethereum/Executive.h>
|
||||
#include <libsolidity/CompilerStack.h>
|
||||
#include <libsolidity/Exceptions.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
@ -57,6 +58,14 @@ public:
|
||||
return m_output;
|
||||
}
|
||||
|
||||
template <class Exceptiontype>
|
||||
void compileRequireThrow(std::string const& _sourceCode)
|
||||
{
|
||||
m_compiler.reset(false, m_addStandardSources);
|
||||
m_compiler.addSource("", _sourceCode);
|
||||
BOOST_REQUIRE_THROW(m_compiler.compile(m_optimize, m_optimizeRuns), Exceptiontype);
|
||||
}
|
||||
|
||||
bytes const& compileAndRun(
|
||||
std::string const& _sourceCode,
|
||||
u256 const& _value = 0,
|
||||
|
Loading…
Reference in New Issue
Block a user