Skip to content

Commit 1d14a4d

Browse files
committed
[isoltest] Add support for events using effects.
1 parent a1c6550 commit 1d14a4d

File tree

6 files changed

+133
-7
lines changed

6 files changed

+133
-7
lines changed

test/ExecutionFramework.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <test/evmc/evmc.hpp>
2929

30+
#include <libsolidity/util/SoltestTypes.h>
3031
#include <libsolutil/CommonIO.h>
3132
#include <libsolutil/FunctionSelector.h>
3233

@@ -282,3 +283,21 @@ bool ExecutionFramework::storageEmpty(h160 const& _addr)
282283
}
283284
return true;
284285
}
286+
287+
vector<solidity::frontend::test::LogRecord> ExecutionFramework::recordedLogs() const
288+
{
289+
vector<solidity::frontend::test::LogRecord> logs{};
290+
for (size_t logIdx = 0; logIdx < numLogs(); ++logIdx)
291+
{
292+
solidity::frontend::test::LogRecord record;
293+
const auto& data = m_evmcHost->recorded_logs.at(logIdx).data;
294+
record.index = logIdx;
295+
record.data = bytes{data.begin(), data.end()};
296+
record.creator = EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(logIdx).creator);
297+
for (size_t topicIdx = 0; topicIdx < numLogTopics(logIdx); ++topicIdx) {
298+
record.topics.emplace_back(EVMHost::convertFromEVMC(m_evmcHost->recorded_logs.at(logIdx).topics.at(topicIdx)));
299+
}
300+
logs.emplace_back(record);
301+
}
302+
return logs;
303+
}

test/ExecutionFramework.h

+12-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939

4040
#include <boost/test/unit_test.hpp>
4141

42+
namespace solidity::frontend::test
43+
{
44+
struct LogRecord;
45+
}
46+
4247
namespace solidity::test
4348
{
4449
using rational = boost::rational<bigint>;
@@ -240,6 +245,13 @@ class ExecutionFramework
240245
return result;
241246
}
242247

248+
size_t numLogs() const;
249+
size_t numLogTopics(size_t _logIdx) const;
250+
util::h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
251+
util::h160 logAddress(size_t _logIdx) const;
252+
bytes logData(size_t _logIdx) const;
253+
std::vector<solidity::frontend::test::LogRecord> recordedLogs() const;
254+
243255
private:
244256
template <class CppFunction, class... Args>
245257
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
@@ -271,12 +283,6 @@ class ExecutionFramework
271283
bool storageEmpty(util::h160 const& _addr);
272284
bool addressHasCode(util::h160 const& _addr);
273285

274-
size_t numLogs() const;
275-
size_t numLogTopics(size_t _logIdx) const;
276-
util::h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
277-
util::h160 logAddress(size_t _logIdx) const;
278-
bytes logData(size_t _logIdx) const;
279-
280286
langutil::EVMVersion m_evmVersion;
281287
solidity::frontend::RevertStrings m_revertStrings = solidity::frontend::RevertStrings::Default;
282288
solidity::frontend::OptimiserSettings m_optimiserSettings = solidity::frontend::OptimiserSettings::minimal();

test/libsolidity/SemanticTest.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
5252
m_lineOffset(m_reader.lineNumber()),
5353
m_enforceViaYul(enforceViaYul)
5454
{
55+
using namespace placeholders;
56+
5557
auto simpleSmokeBuiltin = [](FunctionCall const& _call) -> std::optional<bytes> {
5658
// This function is only used in test/libsolidity/semanticTests/builtins/smoke.sol.
5759
// It could be removed when we have actual builtins.
@@ -69,11 +71,13 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
6971
m_builtins["smoke_test2"] = simpleSmokeBuiltin;
7072

7173
m_hooks.emplace_back([](FunctionCall const& _call) -> std::vector<std::string> {
72-
if (_call.signature.find("smoke_") != string::npos)
74+
if (_call.signature.find("smoke_") != string::npos)
7375
return {_call.signature};
7476
return {};
7577
});
7678

79+
m_hooks.emplace_back(bind(&SemanticTest::eventHook, this, _1));
80+
7781
string choice = m_reader.stringSetting("compileViaYul", "default");
7882
if (choice == "also")
7983
{
@@ -413,3 +417,19 @@ bool SemanticTest::deploy(
413417
auto output = compileAndRunWithoutCheck(m_sources.sources, _value, _contractName, _arguments, _libraries);
414418
return !output.empty() && m_transactionSuccessful;
415419
}
420+
421+
std::vector<std::string> SemanticTest::eventHook(FunctionCall const&) const
422+
{
423+
vector<LogRecord> recordedLogs = ExecutionFramework::recordedLogs();
424+
vector<string> effects;
425+
for (auto const& log: recordedLogs)
426+
{
427+
effects.emplace_back("log[" + std::to_string(log.index) + "]");
428+
effects.emplace_back(" creator=" + log.creator.hex());
429+
effects.emplace_back(" data=" + util::toHex(log.data));
430+
uint32_t index = 0;
431+
for (auto& topic: log.topics)
432+
effects.emplace_back(" topic[" + std::to_string(index++) + "]=" + topic.hex());
433+
}
434+
return effects;
435+
}

test/libsolidity/SemanticTest.h

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
6363

6464
private:
6565
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _compileViaYul, bool _compileToEwasm);
66+
std::vector<std::string> eventHook(FunctionCall const&) const;
67+
6668
SourceMap m_sources;
6769
std::size_t m_lineOffset;
6870
std::vector<TestFunctionCall> m_tests;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
contract ClientReceipt {
2+
event A(address _from, bytes32 _id, uint _value);
3+
event B(address _from, bytes32 _id, uint indexed _value) anonymous;
4+
event C(address _from, bytes32 indexed _id, uint _value);
5+
function deposit(bytes32 _id) public payable returns(uint256) {
6+
emit A(msg.sender, _id, msg.value);
7+
emit B(msg.sender, _id, msg.value);
8+
emit C(msg.sender, _id, msg.value);
9+
return msg.value;
10+
}
11+
}
12+
13+
// ====
14+
// compileViaYul: false
15+
// ----
16+
// deposit(bytes32), 28 wei: 0x1234 -> 0x1c
17+
// - log[0]
18+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
19+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234000000000000000000000000000000000000000000000000000000000000001c
20+
// - topic[0]=4fc165c1791d8130b22d77072206f18d5758860a80083a7c42bc6a92e110165e
21+
// - log[1]
22+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
23+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234
24+
// - topic[0]=000000000000000000000000000000000000000000000000000000000000001c
25+
// - log[2]
26+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
27+
// - data=0000000000000000000000001212121212121212121212121212120000000012000000000000000000000000000000000000000000000000000000000000001c
28+
// - topic[0]=e5a9085dd580c79db234ea99d65ef968e0bfacc80750cb730bf09eac20c220f3
29+
// - topic[1]=0000000000000000000000000000000000000000000000000000000000001234
30+
// deposit(bytes32), 28 wei: 0x1234 -> 0x1c
31+
// - log[0]
32+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
33+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234000000000000000000000000000000000000000000000000000000000000001c
34+
// - topic[0]=4fc165c1791d8130b22d77072206f18d5758860a80083a7c42bc6a92e110165e
35+
// - log[1]
36+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
37+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234
38+
// - topic[0]=000000000000000000000000000000000000000000000000000000000000001c
39+
// - log[2]
40+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
41+
// - data=0000000000000000000000001212121212121212121212121212120000000012000000000000000000000000000000000000000000000000000000000000001c
42+
// - topic[0]=e5a9085dd580c79db234ea99d65ef968e0bfacc80750cb730bf09eac20c220f3
43+
// - topic[1]=0000000000000000000000000000000000000000000000000000000000001234
44+
// deposit(bytes32), 28 wei: 0x1234 -> 0x1c
45+
// - log[0]
46+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
47+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234000000000000000000000000000000000000000000000000000000000000001c
48+
// - topic[0]=4fc165c1791d8130b22d77072206f18d5758860a80083a7c42bc6a92e110165e
49+
// - log[1]
50+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
51+
// - data=00000000000000000000000012121212121212121212121212121200000000120000000000000000000000000000000000000000000000000000000000001234
52+
// - topic[0]=000000000000000000000000000000000000000000000000000000000000001c
53+
// - log[2]
54+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
55+
// - data=0000000000000000000000001212121212121212121212121212120000000012000000000000000000000000000000000000000000000000000000000000001c
56+
// - topic[0]=e5a9085dd580c79db234ea99d65ef968e0bfacc80750cb730bf09eac20c220f3
57+
// - topic[1]=0000000000000000000000000000000000000000000000000000000000001234

test/libsolidity/util/SoltestTypes.h

+22
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,26 @@ struct FunctionCall
307307
using Builtin = std::function<std::optional<bytes>(FunctionCall const&)>;
308308
using Hook = std::function<std::vector<std::string>(FunctionCall const&)>;
309309

310+
/// LogRecord
311+
struct LogRecord
312+
{
313+
size_t index;
314+
/// The address of the account which created the log.
315+
util::h160 creator;
316+
/// The data attached to the log.
317+
bytes data;
318+
/// The log topics.
319+
std::vector<util::h256> topics;
320+
/// Equal operator.
321+
bool operator==(const LogRecord& other) const noexcept
322+
{
323+
return creator == other.creator && data == other.data && topics == other.topics;
324+
}
325+
326+
bool operator!=(const LogRecord& other) const noexcept
327+
{
328+
return !operator==(other);
329+
}
330+
};
331+
310332
}

0 commit comments

Comments
 (0)