mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Use evmone for testing.
This commit is contained in:
parent
7401fbabd9
commit
3dec3af638
@ -33,6 +33,7 @@
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
/// Operators need to stay in the global namespace.
|
||||
|
||||
|
@ -95,19 +95,19 @@ void CommonOptions::validate() const
|
||||
"Invalid test path specified."
|
||||
);
|
||||
|
||||
if (!disableIPC)
|
||||
{
|
||||
assertThrow(
|
||||
!ipcPath.empty(),
|
||||
ConfigException,
|
||||
"No ipc path specified. The --ipcpath argument must not be empty when given."
|
||||
);
|
||||
assertThrow(
|
||||
fs::exists(ipcPath),
|
||||
ConfigException,
|
||||
"Invalid ipc path specified."
|
||||
);
|
||||
}
|
||||
// if (!disableIPC)
|
||||
// {
|
||||
// assertThrow(
|
||||
// !ipcPath.empty(),
|
||||
// ConfigException,
|
||||
// "No ipc path specified. The --ipcpath argument must not be empty when given."
|
||||
// );
|
||||
// assertThrow(
|
||||
// fs::exists(ipcPath),
|
||||
// ConfigException,
|
||||
// "Invalid ipc path specified."
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
bool CommonOptions::parse(int argc, char const* const* argv)
|
||||
|
@ -33,9 +33,52 @@ using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::test;
|
||||
|
||||
EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::vm& _vmInstance):
|
||||
m_vm(_vmInstance)
|
||||
namespace
|
||||
{
|
||||
|
||||
|
||||
evmc::vm& getVM()
|
||||
{
|
||||
static unique_ptr<evmc::vm> theVM;
|
||||
if (!theVM)
|
||||
{
|
||||
// TODO make this an option
|
||||
for (auto path: {
|
||||
"deps/lib/libevmone.so",
|
||||
"../deps/lib/libevmone.so",
|
||||
"/usr/lib/libevmone.so",
|
||||
"/usr/local/lib/libevmone.so",
|
||||
// TODO the circleci docker image somehow only has the .a file
|
||||
"/usr/lib/libevmone.a"
|
||||
})
|
||||
{
|
||||
evmc_loader_error_code errorCode = {};
|
||||
evmc_instance* vm = evmc_load_and_create(path, &errorCode);
|
||||
if (!vm || errorCode != EVMC_LOADER_SUCCESS)
|
||||
continue;
|
||||
theVM = make_unique<evmc::vm>(vm);
|
||||
break;
|
||||
}
|
||||
if (!theVM)
|
||||
{
|
||||
cerr << "Unable to find library libevmone.so" << endl;
|
||||
assertThrow(false, Exception, "");
|
||||
}
|
||||
}
|
||||
return *theVM;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::vm* _vm):
|
||||
m_vm(_vm)
|
||||
{
|
||||
if (!m_vm)
|
||||
{
|
||||
cerr << "Unable to find library libevmone.so" << endl;
|
||||
assertThrow(false, Exception, "");
|
||||
}
|
||||
|
||||
if (_evmVersion == langutil::EVMVersion::homestead())
|
||||
m_evmVersion = EVMC_HOMESTEAD;
|
||||
else if (_evmVersion == langutil::EVMVersion::tangerineWhistle())
|
||||
@ -123,7 +166,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
|
||||
evmc_address currentAddress = m_currentAddress;
|
||||
m_currentAddress = message.destination;
|
||||
evmc::result result = m_vm.execute(*this, m_evmVersion, message, code.data(), code.size());
|
||||
evmc::result result = m_vm->execute(*this, m_evmVersion, message, code.data(), code.size());
|
||||
m_currentAddress = currentAddress;
|
||||
|
||||
if (result.status_code != EVMC_SUCCESS)
|
||||
|
@ -38,7 +38,7 @@ using Address = h160;
|
||||
class EVMHost: public evmc::Host
|
||||
{
|
||||
public:
|
||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::vm& _vmInstance);
|
||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::vm* _vm = getVM());
|
||||
|
||||
struct Account
|
||||
{
|
||||
@ -147,11 +147,6 @@ public:
|
||||
size_t _topicsCount
|
||||
) noexcept;
|
||||
|
||||
evmc_revision getRevision()
|
||||
{
|
||||
return m_evmVersion;
|
||||
}
|
||||
|
||||
static Address convertFromEVMC(evmc_address const& _addr);
|
||||
static evmc_address convertToEVMC(Address const& _addr);
|
||||
static h256 convertFromEVMC(evmc_bytes32 const& _data);
|
||||
@ -165,7 +160,7 @@ public:
|
||||
private:
|
||||
evmc::result precompileSha256(evmc_message const& _message) noexcept;
|
||||
|
||||
evmc::vm& m_vm;
|
||||
evmc::vm* m_vm = nullptr;
|
||||
evmc_revision m_evmVersion;
|
||||
};
|
||||
|
||||
|
@ -22,57 +22,44 @@
|
||||
|
||||
#include <test/ExecutionFramework.h>
|
||||
|
||||
#include <libdevcore/CommonIO.h>
|
||||
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <test/evmc/evmc.hpp>
|
||||
#include <test/evmc/loader.h>
|
||||
#include <test/evmc/helpers.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <libdevcore/CommonIO.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::test;
|
||||
|
||||
namespace // anonymous
|
||||
{
|
||||
|
||||
h256 const EmptyTrie("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
|
||||
|
||||
string getIPCSocketPath()
|
||||
{
|
||||
string ipcPath = dev::test::Options::get().ipcPath.string();
|
||||
if (ipcPath.empty())
|
||||
BOOST_FAIL("ERROR: ipcPath not set! (use --ipcpath <path> or the environment variable ETH_TEST_IPC)");
|
||||
|
||||
return ipcPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ExecutionFramework::ExecutionFramework():
|
||||
ExecutionFramework(getIPCSocketPath(), dev::test::Options::get().evmVersion())
|
||||
ExecutionFramework(dev::test::Options::get().evmVersion())
|
||||
{
|
||||
}
|
||||
|
||||
ExecutionFramework::ExecutionFramework(string const& _ipcPath, langutil::EVMVersion _evmVersion):
|
||||
m_rpc(RPCSession::instance(_ipcPath)),
|
||||
ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_optimiserSettings(solidity::OptimiserSettings::minimal()),
|
||||
m_showMessages(dev::test::Options::get().showMessages),
|
||||
m_sender(m_rpc.account(0))
|
||||
m_evmHost(make_shared<EVMHost>(m_evmVersion))
|
||||
{
|
||||
if (dev::test::Options::get().optimizeYul)
|
||||
m_optimiserSettings = solidity::OptimiserSettings::full();
|
||||
else if (dev::test::Options::get().optimize)
|
||||
m_optimiserSettings = solidity::OptimiserSettings::standard();
|
||||
m_rpc.test_rewindToBlock(0);
|
||||
m_evmHost->reset();
|
||||
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
m_evmHost->m_state.accounts[EVMHost::convertToEVMC(account(i))].balance =
|
||||
EVMHost::convertToEVMC(u256(1) << 100);
|
||||
|
||||
}
|
||||
|
||||
std::pair<bool, string> ExecutionFramework::compareAndCreateMessage(
|
||||
@ -103,22 +90,28 @@ std::pair<bool, string> ExecutionFramework::compareAndCreateMessage(
|
||||
|
||||
u256 ExecutionFramework::gasLimit() const
|
||||
{
|
||||
auto latestBlock = m_rpc.eth_getBlockByNumber("latest", false);
|
||||
return u256(latestBlock["gasLimit"].asString());
|
||||
return {m_evmHost->get_tx_context().block_gas_limit};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::gasPrice() const
|
||||
{
|
||||
return u256(m_rpc.eth_gasPrice());
|
||||
return {EVMHost::convertFromEVMC(m_evmHost->get_tx_context().tx_gas_price)};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockHash(u256 const& _blockNumber) const
|
||||
u256 ExecutionFramework::blockHash(u256 const& _number) const
|
||||
{
|
||||
return u256(m_rpc.eth_getBlockByNumber(toHex(_blockNumber, HexPrefix::Add), false)["hash"].asString());
|
||||
return {EVMHost::convertFromEVMC(m_evmHost->get_block_hash(uint64_t(_number & numeric_limits<uint64_t>::max())))};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockNumber() const
|
||||
{
|
||||
return m_evmHost->m_state.blockNumber;
|
||||
}
|
||||
|
||||
void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
|
||||
{
|
||||
m_evmHost->newBlock();
|
||||
|
||||
if (m_showMessages)
|
||||
{
|
||||
if (_isCreation)
|
||||
@ -129,104 +122,121 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
cout << " value: " << _value << endl;
|
||||
cout << " in: " << toHex(_data) << endl;
|
||||
}
|
||||
RPCSession::TransactionData d;
|
||||
d.data = "0x" + toHex(_data);
|
||||
d.from = "0x" + toString(m_sender);
|
||||
d.gas = toHex(m_gas, HexPrefix::Add);
|
||||
d.gasPrice = toHex(m_gasPrice, HexPrefix::Add);
|
||||
d.value = toHex(_value, HexPrefix::Add);
|
||||
if (!_isCreation)
|
||||
{
|
||||
d.to = dev::toString(m_contractAddress);
|
||||
BOOST_REQUIRE(m_rpc.eth_getCode(d.to, "pending").size() > 2);
|
||||
// Use eth_call to get the output
|
||||
m_output = fromHex(m_rpc.eth_call(d, "pending"), WhenError::Throw);
|
||||
}
|
||||
|
||||
string txHash = m_rpc.eth_sendTransaction(d);
|
||||
m_rpc.rpcCall("eth_flush");
|
||||
m_rpc.test_mineBlocks(1);
|
||||
RPCSession::TransactionReceipt receipt(m_rpc.eth_getTransactionReceipt(txHash));
|
||||
|
||||
m_blockNumber = u256(receipt.blockNumber);
|
||||
evmc_message message = {};
|
||||
message.input_data = _data.data();
|
||||
message.input_size = _data.size();
|
||||
message.sender = EVMHost::convertToEVMC(m_sender);
|
||||
message.value = EVMHost::convertToEVMC(_value);
|
||||
|
||||
if (_isCreation)
|
||||
{
|
||||
m_contractAddress = Address(receipt.contractAddress);
|
||||
BOOST_REQUIRE(m_contractAddress);
|
||||
string code = m_rpc.eth_getCode(receipt.contractAddress, "latest");
|
||||
m_output = fromHex(code, WhenError::Throw);
|
||||
message.kind = EVMC_CREATE;
|
||||
message.destination = EVMHost::convertToEVMC(Address{});
|
||||
}
|
||||
else
|
||||
{
|
||||
message.kind = EVMC_CALL;
|
||||
message.destination = EVMHost::convertToEVMC(m_contractAddress);
|
||||
}
|
||||
message.gas = m_gas.convert_to<int64_t>();
|
||||
|
||||
evmc::result result = m_evmHost->call(message);
|
||||
|
||||
m_output = bytes(result.output_data, result.output_data + result.output_size);
|
||||
if (_isCreation)
|
||||
m_contractAddress = EVMHost::convertFromEVMC(result.create_address);
|
||||
|
||||
m_gasUsed = m_gas - result.gas_left;
|
||||
m_transactionSuccessful = (result.status_code == EVMC_SUCCESS);
|
||||
|
||||
if (m_showMessages)
|
||||
{
|
||||
cout << " out: " << toHex(m_output) << endl;
|
||||
cout << " tx hash: " << txHash << endl;
|
||||
cout << " result: " << size_t(result.status_code) << endl;
|
||||
cout << " gas used: " << m_gasUsed.str() << endl;
|
||||
}
|
||||
|
||||
m_gasUsed = u256(receipt.gasUsed);
|
||||
m_logs.clear();
|
||||
for (auto const& log: receipt.logEntries)
|
||||
{
|
||||
LogEntry entry;
|
||||
entry.address = Address(log.address);
|
||||
for (auto const& topic: log.topics)
|
||||
entry.topics.push_back(h256(topic));
|
||||
entry.data = fromHex(log.data, WhenError::Throw);
|
||||
m_logs.push_back(entry);
|
||||
}
|
||||
|
||||
if (!receipt.status.empty())
|
||||
m_transactionSuccessful = (receipt.status == "1");
|
||||
else
|
||||
m_transactionSuccessful = (m_gas != m_gasUsed);
|
||||
}
|
||||
|
||||
void ExecutionFramework::sendEther(Address const& _to, u256 const& _value)
|
||||
void ExecutionFramework::sendEther(Address const& _addr, u256 const& _amount)
|
||||
{
|
||||
RPCSession::TransactionData d;
|
||||
d.data = "0x";
|
||||
d.from = "0x" + toString(m_sender);
|
||||
d.gas = toHex(m_gas, HexPrefix::Add);
|
||||
d.gasPrice = toHex(m_gasPrice, HexPrefix::Add);
|
||||
d.value = toHex(_value, HexPrefix::Add);
|
||||
d.to = dev::toString(_to);
|
||||
m_evmHost->newBlock();
|
||||
|
||||
string txHash = m_rpc.eth_sendTransaction(d);
|
||||
m_rpc.test_mineBlocks(1);
|
||||
if (m_showMessages)
|
||||
{
|
||||
cout << "SEND_ETHER " << m_sender.hex() << " -> " << _addr.hex() << ":" << endl;
|
||||
if (_amount > 0)
|
||||
cout << " value: " << _amount << endl;
|
||||
}
|
||||
evmc_message message = {};
|
||||
message.sender = EVMHost::convertToEVMC(m_sender);
|
||||
message.value = EVMHost::convertToEVMC(_amount);
|
||||
message.kind = EVMC_CALL;
|
||||
message.destination = EVMHost::convertToEVMC(_addr);
|
||||
message.gas = m_gas.convert_to<int64_t>();
|
||||
|
||||
m_evmHost->call(message);
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::currentTimestamp()
|
||||
{
|
||||
auto latestBlock = m_rpc.eth_getBlockByNumber("latest", false);
|
||||
return size_t(u256(latestBlock.get("timestamp", "invalid").asString()));
|
||||
return m_evmHost->get_tx_context().block_timestamp;
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::blockTimestamp(u256 _number)
|
||||
size_t ExecutionFramework::blockTimestamp(u256 _block)
|
||||
{
|
||||
auto latestBlock = m_rpc.eth_getBlockByNumber(toString(_number), false);
|
||||
return size_t(u256(latestBlock.get("timestamp", "invalid").asString()));
|
||||
if (_block > blockNumber())
|
||||
return 0;
|
||||
else
|
||||
return size_t((currentTimestamp() / blockNumber()) * _block);
|
||||
}
|
||||
|
||||
Address ExecutionFramework::account(size_t _i)
|
||||
Address ExecutionFramework::account(size_t _idx)
|
||||
{
|
||||
return Address(m_rpc.accountCreateIfNotExists(_i));
|
||||
return Address(h256(u256{"0x1212121212121212121212121212120000000012"} + _idx * 0x1000), Address::AlignRight);
|
||||
}
|
||||
|
||||
bool ExecutionFramework::addressHasCode(Address const& _addr)
|
||||
{
|
||||
string code = m_rpc.eth_getCode(toString(_addr), "latest");
|
||||
return !code.empty() && code != "0x";
|
||||
return m_evmHost->get_code_size(EVMHost::convertToEVMC(_addr)) != 0;
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::numLogs() const
|
||||
{
|
||||
return m_evmHost->m_state.logs.size();
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::numLogTopics(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).topics.size();
|
||||
}
|
||||
|
||||
h256 ExecutionFramework::logTopic(size_t _logIdx, size_t _topicIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).topics.at(_topicIdx);
|
||||
}
|
||||
|
||||
Address ExecutionFramework::logAddress(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).address;
|
||||
}
|
||||
|
||||
bytes const& ExecutionFramework::logData(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).data;
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::balanceAt(Address const& _addr)
|
||||
{
|
||||
return u256(m_rpc.eth_getBalance(toString(_addr), "latest"));
|
||||
return u256(EVMHost::convertFromEVMC(m_evmHost->get_balance(EVMHost::convertToEVMC(_addr))));
|
||||
}
|
||||
|
||||
bool ExecutionFramework::storageEmpty(Address const& _addr)
|
||||
{
|
||||
h256 root(m_rpc.eth_getStorageRoot(toString(_addr), "latest"));
|
||||
BOOST_CHECK(root);
|
||||
return root == EmptyTrie;
|
||||
if (EVMHost::Account const* acc = m_evmHost->account(EVMHost::convertToEVMC(_addr)))
|
||||
{
|
||||
for (auto const& entry: acc->storage)
|
||||
if (!(entry.second == evmc_bytes32{}))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/RPCSession.h>
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
|
||||
@ -38,24 +37,26 @@ namespace dev
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
using rational = boost::rational<dev::bigint>;
|
||||
/// An Ethereum address: 20 bytes.
|
||||
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
|
||||
using Address = h160;
|
||||
class EVMHost;
|
||||
|
||||
// The various denominations; here for ease of use where needed within code.
|
||||
static const u256 wei = 1;
|
||||
static const u256 shannon = u256("1000000000");
|
||||
static const u256 szabo = shannon * 1000;
|
||||
static const u256 finney = szabo * 1000;
|
||||
static const u256 ether = finney * 1000;
|
||||
using rational = boost::rational<dev::bigint>;
|
||||
/// An Ethereum address: 20 bytes.
|
||||
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
|
||||
using Address = h160;
|
||||
|
||||
// The various denominations; here for ease of use where needed within code.
|
||||
static const u256 wei = 1;
|
||||
static const u256 shannon = u256("1000000000");
|
||||
static const u256 szabo = shannon * 1000;
|
||||
static const u256 finney = szabo * 1000;
|
||||
static const u256 ether = finney * 1000;
|
||||
|
||||
class ExecutionFramework
|
||||
{
|
||||
|
||||
public:
|
||||
ExecutionFramework();
|
||||
explicit ExecutionFramework(std::string const& _ipcPath, langutil::EVMVersion _evmVersion);
|
||||
explicit ExecutionFramework(langutil::EVMVersion _evmVersion);
|
||||
virtual ~ExecutionFramework() = default;
|
||||
|
||||
virtual bytes const& compileAndRunWithoutCheck(
|
||||
@ -200,9 +201,7 @@ public:
|
||||
u256 gasLimit() const;
|
||||
u256 gasPrice() const;
|
||||
u256 blockHash(u256 const& _blockNumber) const;
|
||||
u256 const& blockNumber() const {
|
||||
return m_blockNumber;
|
||||
}
|
||||
u256 blockNumber() const;
|
||||
|
||||
template<typename Range>
|
||||
static bytes encodeArray(bool _dynamicallySized, bool _dynamicallyEncoded, Range const& _elements)
|
||||
@ -257,26 +256,23 @@ protected:
|
||||
bool storageEmpty(Address const& _addr);
|
||||
bool addressHasCode(Address const& _addr);
|
||||
|
||||
RPCSession& m_rpc;
|
||||
|
||||
struct LogEntry
|
||||
{
|
||||
Address address;
|
||||
std::vector<h256> topics;
|
||||
bytes data;
|
||||
};
|
||||
size_t numLogs() const;
|
||||
size_t numLogTopics(size_t _logIdx) const;
|
||||
h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
|
||||
Address logAddress(size_t _logIdx) const;
|
||||
bytes const& logData(size_t _logIdx) const;
|
||||
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
solidity::OptimiserSettings m_optimiserSettings = solidity::OptimiserSettings::minimal();
|
||||
bool m_showMessages = false;
|
||||
std::shared_ptr<EVMHost> m_evmHost;
|
||||
|
||||
bool m_transactionSuccessful = true;
|
||||
Address m_sender;
|
||||
Address m_sender = account(0);
|
||||
Address m_contractAddress;
|
||||
u256 m_blockNumber;
|
||||
u256 const m_gasPrice = 100 * szabo;
|
||||
u256 const m_gas = 100000000;
|
||||
bytes m_output;
|
||||
std::vector<LogEntry> m_logs;
|
||||
u256 m_gasUsed;
|
||||
};
|
||||
|
||||
|
@ -1,396 +0,0 @@
|
||||
/*
|
||||
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/>.
|
||||
|
||||
The Implementation originally from https://msdn.microsoft.com/en-us/library/windows/desktop/aa365592(v=vs.85).aspx
|
||||
*/
|
||||
/// @file RPCSession.cpp
|
||||
/// Low-level IPC communication between the test framework and the Ethereum node.
|
||||
|
||||
#include <test/RPCSession.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
|
||||
#include <libdevcore/CommonData.h>
|
||||
|
||||
#include <libdevcore/JSON.h>
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
|
||||
IPCSocket::IPCSocket(string const& _path): m_path(_path)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
m_socket = CreateFile(
|
||||
m_path.c_str(), // pipe name
|
||||
GENERIC_READ | // read and write access
|
||||
GENERIC_WRITE,
|
||||
0, // no sharing
|
||||
NULL, // default security attribute
|
||||
OPEN_EXISTING, // opens existing pipe
|
||||
0, // default attributes
|
||||
NULL); // no template file
|
||||
|
||||
if (m_socket == INVALID_HANDLE_VALUE)
|
||||
BOOST_FAIL("Error creating IPC socket object!");
|
||||
|
||||
#else
|
||||
if (_path.length() >= sizeof(sockaddr_un::sun_path))
|
||||
BOOST_FAIL("Error opening IPC: socket path is too long!");
|
||||
|
||||
struct sockaddr_un saun;
|
||||
memset(&saun, 0, sizeof(sockaddr_un));
|
||||
saun.sun_family = AF_UNIX;
|
||||
strcpy(saun.sun_path, _path.c_str());
|
||||
|
||||
// http://idletechnology.blogspot.ca/2011/12/unix-domain-sockets-on-osx.html
|
||||
//
|
||||
// SUN_LEN() might be optimal, but it seemingly affects the portability,
|
||||
// with at least Android missing this macro. Just using the sizeof() for
|
||||
// structure seemingly works, and would only have the side-effect of
|
||||
// sending larger-than-required packets over the socket. Given that this
|
||||
// code is only used for unit-tests, that approach seems simpler.
|
||||
#if defined(__APPLE__)
|
||||
saun.sun_len = sizeof(struct sockaddr_un);
|
||||
#endif // defined(__APPLE__)
|
||||
|
||||
if ((m_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
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
|
||||
}
|
||||
|
||||
string IPCSocket::sendRequest(string const& _req)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// Write to the pipe.
|
||||
DWORD cbWritten;
|
||||
BOOL fSuccess = WriteFile(
|
||||
m_socket, // pipe handle
|
||||
_req.c_str(), // message
|
||||
_req.size(), // message length
|
||||
&cbWritten, // bytes written
|
||||
NULL); // not overlapped
|
||||
|
||||
if (!fSuccess || (_req.size() != cbWritten))
|
||||
BOOST_FAIL("WriteFile to pipe failed");
|
||||
|
||||
// Read from the pipe.
|
||||
DWORD cbRead;
|
||||
fSuccess = ReadFile(
|
||||
m_socket, // pipe handle
|
||||
m_readBuf, // buffer to receive reply
|
||||
sizeof(m_readBuf), // size of buffer
|
||||
&cbRead, // number of bytes read
|
||||
NULL); // not overlapped
|
||||
|
||||
if (!fSuccess)
|
||||
BOOST_FAIL("ReadFile from pipe failed");
|
||||
|
||||
return string(m_readBuf, m_readBuf + cbRead);
|
||||
#else
|
||||
if (send(m_socket, _req.c_str(), _req.length(), 0) != (ssize_t)_req.length())
|
||||
BOOST_FAIL("Writing on IPC failed.");
|
||||
|
||||
auto start = chrono::steady_clock::now();
|
||||
ssize_t ret;
|
||||
do
|
||||
{
|
||||
ret = recv(m_socket, m_readBuf, sizeof(m_readBuf), 0);
|
||||
// Also consider closed socket an error.
|
||||
if (ret < 0)
|
||||
BOOST_FAIL("Reading on IPC failed.");
|
||||
}
|
||||
while (
|
||||
ret == 0 &&
|
||||
chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start).count() < m_readTimeOutMS
|
||||
);
|
||||
|
||||
if (ret == 0)
|
||||
BOOST_FAIL("Timeout reading on IPC.");
|
||||
|
||||
return string(m_readBuf, m_readBuf + ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
RPCSession& RPCSession::instance(string const& _path)
|
||||
{
|
||||
try
|
||||
{
|
||||
static RPCSession session(_path);
|
||||
BOOST_REQUIRE_EQUAL(session.m_ipcSocket.path(), _path);
|
||||
return session;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Error creating RPC session for socket: " + _path));
|
||||
}
|
||||
}
|
||||
|
||||
string RPCSession::eth_getCode(string const& _address, string const& _blockNumber)
|
||||
{
|
||||
return rpcCall("eth_getCode", { quote(_address), quote(_blockNumber) }).asString();
|
||||
}
|
||||
|
||||
Json::Value RPCSession::eth_getBlockByNumber(string const& _blockNumber, bool _fullObjects)
|
||||
{
|
||||
// NOTE: to_string() converts bool to 0 or 1
|
||||
return rpcCall("eth_getBlockByNumber", { quote(_blockNumber), _fullObjects ? "true" : "false" });
|
||||
}
|
||||
|
||||
RPCSession::TransactionReceipt RPCSession::eth_getTransactionReceipt(string const& _transactionHash)
|
||||
{
|
||||
TransactionReceipt receipt;
|
||||
Json::Value const result = rpcCall("eth_getTransactionReceipt", { quote(_transactionHash) });
|
||||
receipt.gasUsed = result["gasUsed"].asString();
|
||||
receipt.contractAddress = result["contractAddress"].asString();
|
||||
receipt.blockNumber = result["blockNumber"].asString();
|
||||
if (m_receiptHasStatusField)
|
||||
{
|
||||
BOOST_REQUIRE(!result["status"].isNull());
|
||||
receipt.status = result["status"].asString();
|
||||
}
|
||||
for (auto const& log: result["logs"])
|
||||
{
|
||||
LogEntry entry;
|
||||
entry.address = log["address"].asString();
|
||||
entry.data = log["data"].asString();
|
||||
for (auto const& topic: log["topics"])
|
||||
entry.topics.push_back(topic.asString());
|
||||
receipt.logEntries.push_back(entry);
|
||||
}
|
||||
return receipt;
|
||||
}
|
||||
|
||||
string RPCSession::eth_sendTransaction(TransactionData const& _td)
|
||||
{
|
||||
return rpcCall("eth_sendTransaction", { _td.toJson() }).asString();
|
||||
}
|
||||
|
||||
string RPCSession::eth_call(TransactionData const& _td, string const& _blockNumber)
|
||||
{
|
||||
return rpcCall("eth_call", { _td.toJson(), quote(_blockNumber) }).asString();
|
||||
}
|
||||
|
||||
string RPCSession::eth_sendTransaction(string const& _transaction)
|
||||
{
|
||||
return rpcCall("eth_sendTransaction", { _transaction }).asString();
|
||||
}
|
||||
|
||||
string RPCSession::eth_getBalance(string const& _address, string const& _blockNumber)
|
||||
{
|
||||
string address = (_address.length() == 20) ? "0x" + _address : _address;
|
||||
return rpcCall("eth_getBalance", { quote(address), quote(_blockNumber) }).asString();
|
||||
}
|
||||
|
||||
string RPCSession::eth_getStorageRoot(string const& _address, string const& _blockNumber)
|
||||
{
|
||||
string address = (_address.length() == 20) ? "0x" + _address : _address;
|
||||
return rpcCall("eth_getStorageRoot", { quote(address), quote(_blockNumber) }).asString();
|
||||
}
|
||||
|
||||
string RPCSession::eth_gasPrice()
|
||||
{
|
||||
return rpcCall("eth_gasPrice").asString();
|
||||
}
|
||||
|
||||
void RPCSession::personal_unlockAccount(string const& _address, string const& _password, int _duration)
|
||||
{
|
||||
BOOST_REQUIRE_MESSAGE(
|
||||
rpcCall("personal_unlockAccount", { quote(_address), quote(_password), to_string(_duration) }),
|
||||
"Error unlocking account " + _address
|
||||
);
|
||||
}
|
||||
|
||||
string RPCSession::personal_newAccount(string const& _password)
|
||||
{
|
||||
string addr = rpcCall("personal_newAccount", { quote(_password) }).asString();
|
||||
BOOST_TEST_MESSAGE("Created account " + addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void RPCSession::test_setChainParams(vector<string> const& _accounts)
|
||||
{
|
||||
string forks;
|
||||
if (test::Options::get().evmVersion() >= langutil::EVMVersion::tangerineWhistle())
|
||||
forks += "\"EIP150ForkBlock\": \"0x00\",\n";
|
||||
if (test::Options::get().evmVersion() >= langutil::EVMVersion::spuriousDragon())
|
||||
forks += "\"EIP158ForkBlock\": \"0x00\",\n";
|
||||
if (test::Options::get().evmVersion() >= langutil::EVMVersion::byzantium())
|
||||
{
|
||||
forks += "\"byzantiumForkBlock\": \"0x00\",\n";
|
||||
m_receiptHasStatusField = true;
|
||||
}
|
||||
if (test::Options::get().evmVersion() >= langutil::EVMVersion::constantinople())
|
||||
forks += "\"constantinopleForkBlock\": \"0x00\",\n";
|
||||
if (test::Options::get().evmVersion() >= langutil::EVMVersion::petersburg())
|
||||
forks += "\"constantinopleFixForkBlock\": \"0x00\",\n";
|
||||
static string const c_configString = R"(
|
||||
{
|
||||
"sealEngine": "NoProof",
|
||||
"params": {
|
||||
"accountStartNonce": "0x00",
|
||||
"maximumExtraDataSize": "0x1000000",
|
||||
"blockReward": "0x",
|
||||
"allowFutureBlocks": true,
|
||||
)" + forks + R"(
|
||||
"homesteadForkBlock": "0x00"
|
||||
},
|
||||
"genesis": {
|
||||
"author": "0000000000000010000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"extraData": "0x",
|
||||
"gasLimit": "0x1000000000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"nonce": "0x0000000000000042",
|
||||
"difficulty": "131072"
|
||||
},
|
||||
"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 } } },
|
||||
"0000000000000000000000000000000000000005": { "wei": "1", "precompiled": { "name": "modexp" } },
|
||||
"0000000000000000000000000000000000000006": { "wei": "1", "precompiled": { "name": "alt_bn128_G1_add", "linear": { "base": 500, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000007": { "wei": "1", "precompiled": { "name": "alt_bn128_G1_mul", "linear": { "base": 40000, "word": 0 } } },
|
||||
"0000000000000000000000000000000000000008": { "wei": "1", "precompiled": { "name": "alt_bn128_pairing_product" } }
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
||||
Json::Value config;
|
||||
BOOST_REQUIRE(jsonParseStrict(c_configString, config));
|
||||
for (auto const& account: _accounts)
|
||||
config["accounts"][account]["wei"] = "0x100000000000000000000000000000000000000000";
|
||||
test_setChainParams(jsonCompactPrint(config));
|
||||
}
|
||||
|
||||
void RPCSession::test_setChainParams(string const& _config)
|
||||
{
|
||||
BOOST_REQUIRE(rpcCall("test_setChainParams", { _config }) == true);
|
||||
}
|
||||
|
||||
void RPCSession::test_rewindToBlock(size_t _blockNr)
|
||||
{
|
||||
BOOST_REQUIRE(rpcCall("test_rewindToBlock", { to_string(_blockNr) }) == true);
|
||||
}
|
||||
|
||||
void RPCSession::test_mineBlocks(int _number)
|
||||
{
|
||||
u256 startBlock = fromBigEndian<u256>(fromHex(rpcCall("eth_blockNumber").asString()));
|
||||
BOOST_REQUIRE(rpcCall("test_mineBlocks", { to_string(_number) }, true) == true);
|
||||
BOOST_REQUIRE(fromBigEndian<u256>(fromHex(rpcCall("eth_blockNumber").asString())) == startBlock + _number);
|
||||
}
|
||||
|
||||
void RPCSession::test_modifyTimestamp(size_t _timestamp)
|
||||
{
|
||||
BOOST_REQUIRE(rpcCall("test_modifyTimestamp", { to_string(_timestamp) }) == true);
|
||||
}
|
||||
|
||||
Json::Value RPCSession::rpcCall(string const& _methodName, vector<string> const& _args, bool _canFail)
|
||||
{
|
||||
string request = "{\"jsonrpc\":\"2.0\",\"method\":\"" + _methodName + "\",\"params\":[";
|
||||
for (size_t i = 0; i < _args.size(); ++i)
|
||||
{
|
||||
request += _args[i];
|
||||
if (i + 1 != _args.size())
|
||||
request += ", ";
|
||||
}
|
||||
|
||||
request += "],\"id\":" + to_string(m_rpcSequence) + "}";
|
||||
++m_rpcSequence;
|
||||
|
||||
BOOST_TEST_MESSAGE("Request: " + request);
|
||||
string reply = m_ipcSocket.sendRequest(request);
|
||||
BOOST_TEST_MESSAGE("Reply: " + reply);
|
||||
|
||||
Json::Value result;
|
||||
string errorMsg;
|
||||
if (!jsonParseStrict(reply, result, &errorMsg))
|
||||
BOOST_FAIL("Failed to parse JSON-RPC response: " + errorMsg);
|
||||
|
||||
if (!result.isMember("id") || !result["id"].isUInt())
|
||||
BOOST_FAIL("Badly formatted JSON-RPC response (missing or non-integer \"id\")");
|
||||
if (result["id"].asUInt() != (m_rpcSequence - 1))
|
||||
BOOST_FAIL(
|
||||
"Response identifier mismatch. "
|
||||
"Expected " + to_string(m_rpcSequence - 1) + " but got " + to_string(result["id"].asUInt()) + "."
|
||||
);
|
||||
|
||||
if (result.isMember("error"))
|
||||
{
|
||||
if (_canFail)
|
||||
return Json::Value();
|
||||
|
||||
BOOST_FAIL("Error on JSON-RPC call: " + result["error"]["message"].asString());
|
||||
}
|
||||
|
||||
if (!result.isMember("result") || result["result"].isNull())
|
||||
BOOST_FAIL(
|
||||
"Missing result for JSON-RPC call: " +
|
||||
result.toStyledString() +
|
||||
"\nRequest was " +
|
||||
request
|
||||
);
|
||||
|
||||
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)
|
||||
{
|
||||
while ((_id + 1) > m_accounts.size())
|
||||
accountCreate();
|
||||
return m_accounts[_id];
|
||||
}
|
||||
|
||||
RPCSession::RPCSession(string const& _path):
|
||||
m_ipcSocket(_path)
|
||||
{
|
||||
accountCreate();
|
||||
// This will pre-fund the accounts create prior.
|
||||
test_setChainParams(m_accounts);
|
||||
}
|
||||
|
||||
string RPCSession::TransactionData::toJson() const
|
||||
{
|
||||
Json::Value json;
|
||||
json["from"] = (from.length() == 20) ? "0x" + from : from;
|
||||
json["to"] = (to.length() == 20 || to == "") ? "0x" + to : to;
|
||||
json["gas"] = gas;
|
||||
json["gasprice"] = gasPrice;
|
||||
json["value"] = value;
|
||||
json["data"] = data;
|
||||
return jsonCompactPrint(json);
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
/** @file RPCSession.h
|
||||
* @author Dimtiry Khokhlov <dimitry@ethdev.com>
|
||||
* @date 2016
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#include <json/value.h>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
|
||||
#if defined(_WIN32)
|
||||
class IPCSocket : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit IPCSocket(std::string const& _path);
|
||||
std::string sendRequest(std::string const& _req);
|
||||
~IPCSocket() { CloseHandle(m_socket); }
|
||||
|
||||
std::string const& path() const { return m_path; }
|
||||
|
||||
private:
|
||||
std::string m_path;
|
||||
HANDLE m_socket;
|
||||
TCHAR m_readBuf[512000];
|
||||
};
|
||||
#else
|
||||
class IPCSocket: public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit IPCSocket(std::string const& _path);
|
||||
std::string sendRequest(std::string const& _req);
|
||||
~IPCSocket() {
|
||||
shutdown(m_socket, SHUT_RDWR);
|
||||
close(m_socket);
|
||||
}
|
||||
|
||||
std::string const& path() const { return m_path; }
|
||||
|
||||
private:
|
||||
|
||||
std::string m_path;
|
||||
int m_socket;
|
||||
/// Socket read timeout in milliseconds. Needs to be large because the key generation routine
|
||||
/// might take long.
|
||||
unsigned static constexpr m_readTimeOutMS = 300000;
|
||||
char m_readBuf[512000];
|
||||
};
|
||||
#endif
|
||||
|
||||
class RPCSession: public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
struct TransactionData
|
||||
{
|
||||
std::string from;
|
||||
std::string to;
|
||||
std::string gas;
|
||||
std::string gasPrice;
|
||||
std::string value;
|
||||
std::string data;
|
||||
|
||||
std::string toJson() const;
|
||||
};
|
||||
|
||||
struct LogEntry {
|
||||
std::string address;
|
||||
std::vector<std::string> topics;
|
||||
std::string data;
|
||||
};
|
||||
|
||||
struct TransactionReceipt
|
||||
{
|
||||
std::string gasUsed;
|
||||
std::string contractAddress;
|
||||
std::vector<LogEntry> logEntries;
|
||||
std::string blockNumber;
|
||||
/// note: pre-byzantium the status field will be empty
|
||||
std::string status;
|
||||
};
|
||||
|
||||
static RPCSession& instance(std::string const& _path);
|
||||
|
||||
std::string eth_getCode(std::string const& _address, std::string const& _blockNumber);
|
||||
Json::Value eth_getBlockByNumber(std::string const& _blockNumber, bool _fullObjects);
|
||||
std::string eth_call(TransactionData const& _td, std::string const& _blockNumber);
|
||||
TransactionReceipt eth_getTransactionReceipt(std::string const& _transactionHash);
|
||||
std::string eth_sendTransaction(TransactionData const& _td);
|
||||
std::string eth_sendTransaction(std::string const& _transaction);
|
||||
std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
|
||||
std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber);
|
||||
std::string eth_gasPrice();
|
||||
std::string personal_newAccount(std::string const& _password);
|
||||
void personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration);
|
||||
void test_setChainParams(std::vector<std::string> const& _accounts);
|
||||
void test_setChainParams(std::string const& _config);
|
||||
void test_rewindToBlock(size_t _blockNr);
|
||||
void test_modifyTimestamp(size_t _timestamp);
|
||||
void test_mineBlocks(int _number);
|
||||
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:
|
||||
explicit RPCSession(std::string const& _path);
|
||||
|
||||
inline std::string quote(std::string const& _arg) { return "\"" + _arg + "\""; }
|
||||
/// Parse std::string replacing keywords to values
|
||||
void parseString(std::string& _string, std::map<std::string, std::string> const& _varMap);
|
||||
|
||||
IPCSocket m_ipcSocket;
|
||||
size_t m_rpcSequence = 1;
|
||||
bool m_receiptHasStatusField = false;
|
||||
|
||||
std::vector<std::string> m_accounts;
|
||||
};
|
||||
|
@ -20,11 +20,14 @@
|
||||
* Tests for a fixed fee registrar contract.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||
#include <test/contracts/ContractInterface.h>
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::test;
|
||||
@ -413,7 +416,8 @@ BOOST_AUTO_TEST_CASE(auction_simple)
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// "wait" until auction end
|
||||
m_rpc.test_modifyTimestamp(currentTimestamp() + m_biddingTime + 10);
|
||||
|
||||
m_evmHost->m_state.timestamp += m_biddingTime + 10;
|
||||
// trigger auction again
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||
@ -425,7 +429,7 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
string name = "x";
|
||||
|
||||
unsigned startTime = 0x776347e2;
|
||||
m_rpc.test_modifyTimestamp(startTime);
|
||||
m_evmHost->m_state.timestamp = startTime;
|
||||
|
||||
RegistrarInterface registrar(*this);
|
||||
// initiate auction
|
||||
@ -433,19 +437,19 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// overbid self
|
||||
m_rpc.test_modifyTimestamp(startTime + m_biddingTime - 10);
|
||||
m_evmHost->m_state.timestamp = startTime + m_biddingTime - 10;
|
||||
registrar.setNextValue(12);
|
||||
registrar.reserve(name);
|
||||
// another bid by someone else
|
||||
sendEther(account(1), 10 * ether);
|
||||
m_sender = account(1);
|
||||
m_rpc.test_modifyTimestamp(startTime + 2 * m_biddingTime - 50);
|
||||
m_evmHost->m_state.timestamp = startTime + 2 * m_biddingTime - 50;
|
||||
registrar.setNextValue(13);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// end auction by first bidder (which is not highest) trying to overbid again (too late)
|
||||
m_sender = account(0);
|
||||
m_rpc.test_modifyTimestamp(startTime + 4 * m_biddingTime);
|
||||
m_evmHost->m_state.timestamp = startTime + 4 * m_biddingTime;
|
||||
registrar.setNextValue(20);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), account(1));
|
||||
@ -461,17 +465,17 @@ BOOST_AUTO_TEST_CASE(auction_renewal)
|
||||
// register name by auction
|
||||
registrar.setNextValue(8);
|
||||
registrar.reserve(name);
|
||||
m_rpc.test_modifyTimestamp(startTime + 4 * m_biddingTime);
|
||||
m_evmHost->m_state.timestamp = startTime + 4 * m_biddingTime;
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||
|
||||
// try to re-register before interval end
|
||||
sendEther(account(1), 10 * ether);
|
||||
m_sender = account(1);
|
||||
m_rpc.test_modifyTimestamp(currentTimestamp() + m_renewalInterval - 1);
|
||||
m_evmHost->m_state.timestamp = currentTimestamp() + m_renewalInterval - 1;
|
||||
registrar.setNextValue(80);
|
||||
registrar.reserve(name);
|
||||
m_rpc.test_modifyTimestamp(currentTimestamp() + m_biddingTime);
|
||||
m_evmHost->m_state.timestamp = currentTimestamp() + m_biddingTime;
|
||||
// if there is a bug in the renewal logic, this would transfer the ownership to account(1),
|
||||
// but if there is no bug, this will initiate the auction, albeit with a zero bid
|
||||
registrar.reserve(name);
|
||||
|
@ -377,11 +377,11 @@ BOOST_AUTO_TEST_CASE(transfer_ownership)
|
||||
BOOST_REQUIRE(callContractFunction("setOwner(bytes32,address)", 0x00, ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 2);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("Transfer(bytes32,address)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == u256(0x00));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that owner of 0x00 is now account(1).
|
||||
BOOST_CHECK(callContractFunction("owner(bytes32)", 0x00) == encodeArgs(ACCOUNT(1)));
|
||||
@ -406,11 +406,11 @@ BOOST_AUTO_TEST_CASE(set_resolver)
|
||||
BOOST_REQUIRE(callContractFunction("setResolver(bytes32,address)", 0x00, ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 2);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("NewResolver(bytes32,address)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == u256(0x00));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewResolver(bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that the resolver is changed to account(1).
|
||||
BOOST_CHECK(callContractFunction("resolver(bytes32)", 0x00) == encodeArgs(ACCOUNT(1)));
|
||||
@ -435,11 +435,11 @@ BOOST_AUTO_TEST_CASE(set_ttl)
|
||||
BOOST_REQUIRE(callContractFunction("setTTL(bytes32,uint64)", 0x00, 3600) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(3600));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 2);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("NewTTL(bytes32,uint64)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == u256(0x00));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(3600));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 2);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewTTL(bytes32,uint64)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
|
||||
// Verify that the TTL has been set.
|
||||
BOOST_CHECK(callContractFunction("ttl(bytes32)", 0x00) == encodeArgs(3600));
|
||||
@ -464,12 +464,12 @@ BOOST_AUTO_TEST_CASE(create_subnode)
|
||||
BOOST_REQUIRE(callContractFunction("setSubnodeOwner(bytes32,bytes32,address)", 0x00, keccak256(string("eth")), ACCOUNT(1)) == encodeArgs());
|
||||
|
||||
// Check that an event was raised and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 3);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("NewOwner(bytes32,bytes32,address)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == u256(0x00));
|
||||
BOOST_CHECK(m_logs[0].topics[2] == keccak256(string("eth")));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(ACCOUNT(1)));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("NewOwner(bytes32,bytes32,address)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == u256(0x00));
|
||||
BOOST_CHECK(logTopic(0, 2) == keccak256(string("eth")));
|
||||
|
||||
// Verify that the sub-node owner is now account(1).
|
||||
u256 namehash = keccak256(h256(0x00).asBytes() + keccak256("eth").asBytes());
|
||||
|
@ -494,12 +494,12 @@ BOOST_AUTO_TEST_CASE(transfer_event)
|
||||
BOOST_REQUIRE(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that a Transfer event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 3);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == ACCOUNT(0));
|
||||
BOOST_CHECK(m_logs[0].topics[2] == ACCOUNT(1));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(transfer_zero_no_event)
|
||||
@ -512,7 +512,7 @@ BOOST_AUTO_TEST_CASE(transfer_zero_no_event)
|
||||
BOOST_REQUIRE(callContractFunction("transfer(address,uint256)", ACCOUNT(1), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that no Event was recorded.
|
||||
BOOST_CHECK(m_logs.size() == 0);
|
||||
BOOST_CHECK(numLogs() == 0);
|
||||
|
||||
// Check that balances have not changed.
|
||||
BOOST_CHECK(callContractFunction("balanceOf(address)", ACCOUNT(0)) == encodeArgs(TOKENSUPPLY - transfer));
|
||||
@ -529,12 +529,12 @@ BOOST_AUTO_TEST_CASE(approval_and_transfer_events)
|
||||
BOOST_REQUIRE(callContractFunction("approve(address,uint256)", ACCOUNT(1), u256(allow)) == SUCCESS);
|
||||
|
||||
// Check that an Approval event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(allow));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 3);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("Approval(address,address,uint256)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == ACCOUNT(0));
|
||||
BOOST_CHECK(m_logs[0].topics[2] == ACCOUNT(1));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(allow));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Approval(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(1));
|
||||
|
||||
// Send account(1) some ether for gas.
|
||||
sendEther(account(1), 1000 * ether);
|
||||
@ -546,12 +546,12 @@ BOOST_AUTO_TEST_CASE(approval_and_transfer_events)
|
||||
BOOST_REQUIRE(callContractFunction("transferFrom(address,address,uint256)", ACCOUNT(0), ACCOUNT(2), u256(transfer)) == SUCCESS);
|
||||
|
||||
// Check that a Transfer event was recorded and contents are correct.
|
||||
BOOST_REQUIRE(m_logs.size() == 1);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(m_logs[0].topics.size() == 3);
|
||||
BOOST_CHECK(m_logs[0].topics[0] == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(m_logs[0].topics[1] == ACCOUNT(0));
|
||||
BOOST_CHECK(m_logs[0].topics[2] == ACCOUNT(2));
|
||||
BOOST_REQUIRE(numLogs() == 1);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(transfer));
|
||||
BOOST_REQUIRE(numLogTopics(0) == 3);
|
||||
BOOST_CHECK(logTopic(0, 0) == keccak256(string("Transfer(address,address,uint256)")));
|
||||
BOOST_CHECK(logTopic(0, 1) == ACCOUNT(0));
|
||||
BOOST_CHECK(logTopic(0, 2) == ACCOUNT(2));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(invalid_transfer_1)
|
||||
|
@ -43,9 +43,9 @@ namespace test
|
||||
{
|
||||
|
||||
#define REQUIRE_LOG_DATA(DATA) do { \
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1); \
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); \
|
||||
ABI_CHECK(m_logs[0].data, DATA); \
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1); \
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress); \
|
||||
ABI_CHECK(logData(0), DATA); \
|
||||
} while (false)
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(ABIEncoderTest, SolidityExecutionFramework)
|
||||
@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(structs)
|
||||
);
|
||||
BOOST_CHECK(callContractFunction("f()") == encoded);
|
||||
REQUIRE_LOG_DATA(encoded);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("e(uint16,(uint16,uint16,(uint64[2])[],uint16))")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("e(uint16,(uint16,uint16,(uint64[2])[],uint16))")));
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <test/libsolidity/SolidityExecutionFramework.h>
|
||||
|
||||
#include <test/Options.h>
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
@ -1133,8 +1134,12 @@ BOOST_AUTO_TEST_CASE(blockchain)
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK(m_rpc.rpcCall("miner_setEtherbase", {"\"0x1212121212121212121212121212121212121212\""}).asBool() == true);
|
||||
m_rpc.test_mineBlocks(5);
|
||||
m_evmHost->m_coinbase = EVMHost::convertToEVMC(Address("0x1212121212121212121212121212121212121212"));
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
compileAndRun(sourceCode, 27);
|
||||
ABI_CHECK(callContractFunctionWithValue("someInfo()", 28), encodeArgs(28, u256("0x1212121212121212121212121212121212121212"), 7));
|
||||
}
|
||||
@ -1184,10 +1189,10 @@ BOOST_AUTO_TEST_CASE(now)
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
u256 startBlock = m_blockNumber;
|
||||
u256 startBlock = blockNumber();
|
||||
size_t startTime = blockTimestamp(startBlock);
|
||||
auto ret = callContractFunction("someInfo()");
|
||||
u256 endBlock = m_blockNumber;
|
||||
u256 endBlock = blockNumber();
|
||||
size_t endTime = blockTimestamp(endBlock);
|
||||
BOOST_CHECK(startBlock != endBlock);
|
||||
BOOST_CHECK(startTime != endTime);
|
||||
@ -1276,10 +1281,10 @@ BOOST_AUTO_TEST_CASE(log0)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics.size(), 0);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_CHECK_EQUAL(numLogTopics(0), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log1)
|
||||
@ -1293,11 +1298,11 @@ BOOST_AUTO_TEST_CASE(log1)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], h256(u256(2)));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log2)
|
||||
@ -1311,12 +1316,12 @@ BOOST_AUTO_TEST_CASE(log2)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
for (unsigned i = 0; i < 2; ++i)
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[i], h256(u256(i + 2)));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log3)
|
||||
@ -1330,12 +1335,12 @@ BOOST_AUTO_TEST_CASE(log3)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
for (unsigned i = 0; i < 3; ++i)
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[i], h256(u256(i + 2)));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log4)
|
||||
@ -1349,12 +1354,12 @@ BOOST_AUTO_TEST_CASE(log4)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("a()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 4);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 4);
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[i], h256(u256(i + 2)));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, i), h256(u256(i + 2)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(log_in_constructor)
|
||||
@ -1367,11 +1372,11 @@ BOOST_AUTO_TEST_CASE(log_in_constructor)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], h256(u256(2)));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(u256(2)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(selfdestruct)
|
||||
@ -2615,13 +2620,13 @@ BOOST_AUTO_TEST_CASE(event)
|
||||
for (bool manually: {true, false})
|
||||
{
|
||||
callContractFunctionWithValue("deposit(bytes32,bool)", value, id, manually);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(value)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2640,13 +2645,13 @@ BOOST_AUTO_TEST_CASE(event_emit)
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
callContractFunctionWithValue("deposit(bytes32)", value, id);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(value)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(value)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(id));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2664,11 +2669,11 @@ BOOST_AUTO_TEST_CASE(event_no_arguments)
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data.empty());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0).empty());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit()")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2687,11 +2692,11 @@ BOOST_AUTO_TEST_CASE(event_access_through_base_name_emit)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data.empty());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("x()")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0).empty());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("x()")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(events_with_same_name)
|
||||
@ -2725,32 +2730,32 @@ BOOST_AUTO_TEST_CASE(events_with_same_name)
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("deposit()"), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data.empty());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0).empty());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit()")));
|
||||
|
||||
ABI_CHECK(callContractFunction("deposit(address)", c_loggedAddress), encodeArgs(u256(2)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
ABI_CHECK(m_logs[0].data, encodeArgs(c_loggedAddress));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
ABI_CHECK(logData(0), encodeArgs(c_loggedAddress));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address)")));
|
||||
|
||||
ABI_CHECK(callContractFunction("deposit(address,uint256)", c_loggedAddress, u256(100)), encodeArgs(u256(3)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
ABI_CHECK(m_logs[0].data, encodeArgs(c_loggedAddress, 100));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
ABI_CHECK(logData(0), encodeArgs(c_loggedAddress, 100));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,uint256)")));
|
||||
|
||||
ABI_CHECK(callContractFunction("deposit(address,bool)", c_loggedAddress, false), encodeArgs(u256(4)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
ABI_CHECK(m_logs[0].data, encodeArgs(c_loggedAddress, false));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bool)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
ABI_CHECK(logData(0), encodeArgs(c_loggedAddress, false));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,bool)")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2786,25 +2791,25 @@ BOOST_AUTO_TEST_CASE(events_with_same_name_inherited_emit)
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("deposit()"), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data.empty());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0).empty());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit()")));
|
||||
|
||||
ABI_CHECK(callContractFunction("deposit(address)", c_loggedAddress), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(c_loggedAddress));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(c_loggedAddress));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address)")));
|
||||
|
||||
ABI_CHECK(callContractFunction("deposit(address,uint256)", c_loggedAddress, u256(100)), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
ABI_CHECK(m_logs[0].data, encodeArgs(c_loggedAddress, 100));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
ABI_CHECK(logData(0), encodeArgs(c_loggedAddress, 100));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,uint256)")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2821,7 +2826,7 @@ BOOST_AUTO_TEST_CASE(event_anonymous)
|
||||
ALSO_VIA_YUL(
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 0);
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 0);
|
||||
)
|
||||
}
|
||||
|
||||
@ -2840,14 +2845,14 @@ BOOST_AUTO_TEST_CASE(event_anonymous_with_topics)
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
callContractFunctionWithValue("deposit(bytes32)", value, id);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs("abc"));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 4);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(id));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(value));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[3], h256(2));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs("abc"));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 4);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), h256(m_sender, h256::AlignRight));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), h256(id));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 2), h256(value));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 3), h256(2));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2866,11 +2871,11 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
|
||||
u256 value(18);
|
||||
u256 id(0x1234);
|
||||
callContractFunctionWithValue("deposit(bytes32)", value, id);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs((u160)m_sender, id, value, true));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256,bool)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs((u160)m_sender, id, value, true));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,bytes32,uint256,bool)")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -2886,11 +2891,11 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(toHex(m_logs[0].data), toHex(encodeArgs(10, 0x60, 15, 4, asString(FixedHash<4>(dev::keccak256("deposit()")).asBytes()))));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(toHex(logData(0)), toHex(encodeArgs(10, 0x60, 15, 4, asString(FixedHash<4>(dev::keccak256("deposit()")).asBytes()))));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage)
|
||||
@ -2910,11 +2915,11 @@ BOOST_AUTO_TEST_CASE(event_really_lots_of_data_from_storage)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(toHex(m_logs[0].data), toHex(encodeArgs(10, 0x60, 15, 3, string("ABC"))));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK_EQUAL(toHex(logData(0)), toHex(encodeArgs(10, 0x60, 15, 3, string("ABC"))));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage)
|
||||
@ -2935,11 +2940,11 @@ BOOST_AUTO_TEST_CASE(event_really_really_lots_of_data_from_storage)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(10, 0x60, 15, 31, string("ABC") + string(27, 0) + "Z"));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(10, 0x60, 15, 31, string("ABC") + string(27, 0) + "Z"));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(uint256,bytes,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_struct_memory_v2)
|
||||
@ -2957,11 +2962,11 @@ BOOST_AUTO_TEST_CASE(event_struct_memory_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint256))")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_struct_storage_v2)
|
||||
@ -2981,11 +2986,11 @@ BOOST_AUTO_TEST_CASE(event_struct_storage_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint256))")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(x));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint256))")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_memory)
|
||||
@ -3005,11 +3010,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_memory)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2)
|
||||
@ -3030,11 +3035,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_memory_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_memory_v2)
|
||||
@ -3058,11 +3063,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_memory_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[][])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_dynamic_array_storage)
|
||||
@ -3084,11 +3089,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[])")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -3112,11 +3117,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_array_storage_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 3, x, x + 1, x + 2));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[])")));
|
||||
)
|
||||
}
|
||||
|
||||
@ -3143,11 +3148,11 @@ BOOST_AUTO_TEST_CASE(event_dynamic_nested_array_storage_v2)
|
||||
compileAndRun(sourceCode);
|
||||
u256 x(42);
|
||||
callContractFunction("createEvent(uint256)", x);
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(uint256[][])")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(0x20, 2, 0x40, 0xa0, 2, x, x + 1, 2, x + 2, x + 3));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(uint256[][])")));
|
||||
);
|
||||
}
|
||||
|
||||
@ -3172,18 +3177,18 @@ BOOST_AUTO_TEST_CASE(event_indexed_string)
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
callContractFunction("deposit()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
string dynx(90, 0);
|
||||
for (size_t i = 0; i < dynx.size(); ++i)
|
||||
dynx[i] = i;
|
||||
BOOST_CHECK(m_logs[0].data == bytes());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(dynx));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[2], dev::keccak256(
|
||||
BOOST_CHECK(logData(0) == bytes());
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(dynx));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 2), dev::keccak256(
|
||||
encodeArgs(u256(4), u256(5), u256(6), u256(7))
|
||||
));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(string,uint256[4])")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(string,uint256[4])")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
|
||||
@ -3981,11 +3986,11 @@ BOOST_AUTO_TEST_CASE(storing_invalid_boolean)
|
||||
ABI_CHECK(callContractFunction("perm()"), encodeArgs(1));
|
||||
ABI_CHECK(callContractFunction("ret()"), encodeArgs(1));
|
||||
ABI_CHECK(callContractFunction("ev()"), encodeArgs(1));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_CHECK(m_logs[0].data == encodeArgs(1));
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Ev(bool)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_CHECK(logData(0) == encodeArgs(1));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Ev(bool)")));
|
||||
}
|
||||
|
||||
|
||||
@ -5907,11 +5912,11 @@ BOOST_AUTO_TEST_CASE(invalid_enum_logged)
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
ABI_CHECK(callContractFunction("test_log_ok()"), encodeArgs(u256(1)));
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1);
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Log(uint8)")));
|
||||
BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(0)));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 1);
|
||||
BOOST_REQUIRE_EQUAL(logTopic(0, 0), dev::keccak256(string("Log(uint8)")));
|
||||
BOOST_CHECK_EQUAL(h256(logData(0)), h256(u256(0)));
|
||||
|
||||
// should throw
|
||||
ABI_CHECK(callContractFunction("test_log()"), encodeArgs());
|
||||
@ -13554,13 +13559,13 @@ BOOST_AUTO_TEST_CASE(abi_encodePackedV2_structs)
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes structEnc = encodeArgs(int(0x12), u256(-7), int(2), int(3), u256(-7), u256(-8));
|
||||
ABI_CHECK(callContractFunction("testStorage()"), encodeArgs());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint8,int16,uint8[2],int16[]))")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(asString(structEnc)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint8,int16,uint8[2],int16[]))")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(asString(structEnc)));
|
||||
ABI_CHECK(callContractFunction("testMemory()"), encodeArgs());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint8,int16,uint8[2],int16[]))")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(asString(structEnc)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint8,int16,uint8[2],int16[]))")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(asString(structEnc)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(abi_encodePackedV2_nestedArray)
|
||||
@ -13587,9 +13592,9 @@ BOOST_AUTO_TEST_CASE(abi_encodePackedV2_nestedArray)
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes structEnc = encodeArgs(1, 2, 3, 0, 0, 0, 0, 4);
|
||||
ABI_CHECK(callContractFunction("testNestedArrays()"), encodeArgs());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint8,int16)[2][][3])")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(asString(structEnc)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint8,int16)[2][][3])")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(asString(structEnc)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(abi_encodePackedV2_arrayOfStrings)
|
||||
@ -13616,13 +13621,13 @@ BOOST_AUTO_TEST_CASE(abi_encodePackedV2_arrayOfStrings)
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
bytes arrayEncoding = encodeArgs("abc", "0123456789012345678901234567890123456789");
|
||||
ABI_CHECK(callContractFunction("testStorage()"), encodeArgs());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(string[])")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(asString(arrayEncoding)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(string[])")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(asString(arrayEncoding)));
|
||||
ABI_CHECK(callContractFunction("testMemory()"), encodeArgs());
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E(string[])")));
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[1], dev::keccak256(asString(arrayEncoding)));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E(string[])")));
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 1), dev::keccak256(asString(arrayEncoding)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event_signature_in_library)
|
||||
@ -13649,8 +13654,8 @@ BOOST_AUTO_TEST_CASE(event_signature_in_library)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("E((uint8,int16),(uint8,int16))")));
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 2);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("E((uint8,int16),(uint8,int16))")));
|
||||
}
|
||||
|
||||
|
||||
@ -14730,10 +14735,10 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
|
||||
u256 id(0x1234);
|
||||
|
||||
callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 1);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3);
|
||||
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 1);
|
||||
BOOST_CHECK_EQUAL(logAddress(0), m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(numLogTopics(0), 3);
|
||||
BOOST_CHECK_EQUAL(logTopic(0, 0), dev::keccak256(string("Deposit(address,bytes32,uint256)")));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(uninitialized_internal_storage_function)
|
||||
@ -14801,10 +14806,10 @@ BOOST_AUTO_TEST_CASE(dirty_scratch_space_prior_to_constant_optimiser)
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
BOOST_REQUIRE_EQUAL(m_logs.size(), 2);
|
||||
BOOST_CHECK_EQUAL(m_logs[1].address, m_contractAddress);
|
||||
BOOST_REQUIRE_EQUAL(numLogs(), 2);
|
||||
BOOST_CHECK_EQUAL(logAddress(1), m_contractAddress);
|
||||
ABI_CHECK(
|
||||
m_logs[1].data,
|
||||
logData(1),
|
||||
encodeArgs(u256("0x0000000000001234123412431234123412412342112341234124312341234124"))
|
||||
);
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ SolidityExecutionFramework::SolidityExecutionFramework():
|
||||
{
|
||||
}
|
||||
|
||||
SolidityExecutionFramework::SolidityExecutionFramework(std::string const& _ipcPath, langutil::EVMVersion _evmVersion):
|
||||
ExecutionFramework(_ipcPath, _evmVersion)
|
||||
SolidityExecutionFramework::SolidityExecutionFramework(std::string const&, langutil::EVMVersion _evmVersion):
|
||||
ExecutionFramework(_evmVersion)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ add_executable(isoltest
|
||||
IsolTestOptions.cpp
|
||||
../Options.cpp
|
||||
../Common.cpp
|
||||
../EVMHost.cpp
|
||||
../TestCase.cpp
|
||||
../libsolidity/util/BytesUtils.cpp
|
||||
../libsolidity/util/ContractABIUtils.cpp
|
||||
@ -26,7 +27,6 @@ add_executable(isoltest
|
||||
../libsolidity/AnalysisFramework.cpp
|
||||
../libsolidity/SolidityExecutionFramework.cpp
|
||||
../ExecutionFramework.cpp
|
||||
../RPCSession.cpp
|
||||
../libsolidity/ABIJsonTest.cpp
|
||||
../libsolidity/ASTJSONTest.cpp
|
||||
../libsolidity/SMTCheckerJSONTest.cpp
|
||||
|
@ -142,7 +142,7 @@ DEFINE_PROTO_FUZZER(Contract const& _input)
|
||||
|
||||
// We target the default EVM which is the latest
|
||||
langutil::EVMVersion version = {};
|
||||
EVMHost hostContext(version, evmone);
|
||||
EVMHost hostContext(version, &evmone);
|
||||
|
||||
// Deploy contract and signal failure if deploy failed
|
||||
evmc::result createResult = deployContract(hostContext, byteCode);
|
||||
|
Loading…
Reference in New Issue
Block a user