Skip to content

Commit ca5a695

Browse files
committed
[isoltest] Add support for events using call-effects.
1 parent 7390def commit ca5a695

File tree

9 files changed

+124
-12
lines changed

9 files changed

+124
-12
lines changed

test/ExecutionFramework.cpp

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

test/ExecutionFramework.h

+13-5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <test/Common.h>
2727
#include <test/EVMHost.h>
2828

29+
#include <libsolidity/util/SoltestTypes.h>
2930
#include <libsolidity/interface/OptimiserSettings.h>
3031
#include <libsolidity/interface/DebugSettings.h>
3132

@@ -39,6 +40,11 @@
3940

4041
#include <boost/test/unit_test.hpp>
4142

43+
namespace solidity::frontend::test
44+
{
45+
struct LogRecord;
46+
} // namespace solidity::frontend::test
47+
4248
namespace solidity::test
4349
{
4450
using rational = boost::rational<bigint>;
@@ -241,6 +247,12 @@ class ExecutionFramework
241247
return result;
242248
}
243249

250+
size_t numLogs() const;
251+
size_t numLogTopics(size_t _logIdx) const;
252+
util::h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
253+
util::h160 logAddress(size_t _logIdx) const;
254+
bytes logData(size_t _logIdx) const;
255+
244256
private:
245257
template <class CppFunction, class... Args>
246258
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
@@ -272,11 +284,7 @@ class ExecutionFramework
272284
bool storageEmpty(util::h160 const& _addr);
273285
bool addressHasCode(util::h160 const& _addr);
274286

275-
size_t numLogs() const;
276-
size_t numLogTopics(size_t _logIdx) const;
277-
util::h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
278-
util::h160 logAddress(size_t _logIdx) const;
279-
bytes logData(size_t _logIdx) const;
287+
std::vector<solidity::frontend::test::LogRecord> recordedLogs() const;
280288

281289
langutil::EVMVersion m_evmVersion;
282290
solidity::frontend::RevertStrings m_revertStrings = solidity::frontend::RevertStrings::Default;

test/libsolidity/SemanticTest.cpp

+32-5
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ void SemanticTest::initializeBuiltins()
147147
soltestAssert(_call.arguments.parameters.empty(), "No arguments expected.");
148148
return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0));
149149
};
150+
150151
m_hooks.emplace_back(
151152
[](FunctionCall const& _call) -> std::vector<std::string>
152153
{
@@ -163,17 +164,41 @@ void SemanticTest::initializeBuiltins()
163164
return {};
164165
}
165166
);
167+
using namespace placeholders;
168+
m_hooks.emplace_back(bind(&SemanticTest::eventHook, this, _1));
166169
}
167170

168-
vector<string> SemanticTest::effectsOfCall(FunctionCall const& _call) const
171+
vector<string> SemanticTest::eventHook(FunctionCall const&) const
169172
{
173+
vector<LogRecord> recordedLogs = ExecutionFramework::recordedLogs();
170174
vector<string> effects;
171-
for (auto const& hook: m_hooks)
172-
for (auto const& effect: hook(_call))
173-
effects.emplace_back(effect);
175+
for (auto const& log: recordedLogs)
176+
{
177+
effects.emplace_back("log[" + std::to_string(log.index) + "]");
178+
effects.emplace_back(" creator=" + log.creator.hex());
179+
effects.emplace_back(" data=" + util::toHex(log.data));
180+
uint32_t index = 0;
181+
for (auto& topic: log.topics)
182+
effects.emplace_back(" topic[" + std::to_string(index++) + "]=" + topic.hex());
183+
}
174184
return effects;
175185
}
176186

187+
void SemanticTest::updateEffectsOfCall(FunctionCall const& _call)
188+
{
189+
if (m_effects[&_call].empty())
190+
for (auto const& hook: m_hooks)
191+
for (auto const& effect: hook(_call))
192+
m_effects[&_call].emplace_back(effect);
193+
}
194+
195+
vector<string> SemanticTest::effectsOfCall(FunctionCall const& _call) const
196+
{
197+
if (m_effects.find(&_call) != m_effects.end())
198+
return m_effects.at(&_call);
199+
return {};
200+
}
201+
177202
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
178203
{
179204
TestResult result = TestResult::Success;
@@ -330,6 +355,7 @@ TestCase::TestResult SemanticTest::runTest(
330355
test.setContractABI(m_compiler.contractABI(m_compiler.lastContractName(m_sources.mainSourceFile)));
331356
}
332357

358+
updateEffectsOfCall(test.call());
333359
success &= test.call().effects == effectsOfCall(test.call());
334360
}
335361

@@ -379,7 +405,8 @@ TestCase::TestResult SemanticTest::runTest(
379405
_linePrefix,
380406
TestFunctionCall::RenderMode::ExpectedValuesExpectedGas,
381407
_formatted,
382-
/* _interactivePrint */ true
408+
/* _interactivePrint */ true,
409+
effectsOfCall(test.call())
383410
) << endl;
384411
_stream << errorReporter.format(_linePrefix, _formatted);
385412
}

test/libsolidity/SemanticTest.h

+3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
8181
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun);
8282
bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;
8383
void initializeBuiltins();
84+
void updateEffectsOfCall(FunctionCall const& _call);
8485
std::vector<std::string> effectsOfCall(FunctionCall const& _call) const;
86+
std::vector<std::string> eventHook(FunctionCall const&) const;
8587
SourceMap m_sources;
8688
std::size_t m_lineOffset;
8789
std::vector<TestFunctionCall> m_tests;
@@ -99,6 +101,7 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
99101
bool m_gasCostFailure = false;
100102
bool m_enforceGasCost = false;
101103
u256 m_enforceGasCostMinValue;
104+
std::map<FunctionCall const*, std::vector<std::string>> m_effects{};
102105
};
103106

104107
}

test/libsolidity/semanticTests/externalContracts/deposit_contract.sol

+10-2
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,21 @@ contract DepositContract is IDepositContract, ERC165 {
196196
// gas legacy: 128065
197197
// gas legacyOptimized: 100398
198198
// get_deposit_count() -> 0x20, 8, 0
199-
// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 #
199+
// deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 ->
200+
// - log[0]
201+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
202+
// - data=00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f7329267a8811c397529dac52ae1342ba58c9500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71000000000000000000000000000000000000000000000000000000000000000800ca9a3b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060a29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c1324b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000
203+
// - topic[0]=649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5
200204
// get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438
201205
// gas irOptimized: 104386
202206
// gas legacy: 128075
203207
// gas legacyOptimized: 100411
204208
// get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000
205-
// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac #
209+
// deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d ->
210+
// - log[0]
211+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
212+
// - data=00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030b2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc2228025944106d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771000000000000000000000000000000000000000000000000000000000000000800405973070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d3697595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c560c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d00000000000000000000000000000000000000000000000000000000000000080100000000000000000000000000000000000000000000000000000000000000
213+
// - topic[0]=649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5
206214
// get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee
207215
// gas irOptimized: 104386
208216
// gas legacy: 128075

test/libsolidity/semanticTests/externalContracts/snark.sol

+4
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ contract Test {
296296
// g() -> true
297297
// pair() -> true
298298
// verifyTx() -> true
299+
// - log[0]
300+
// - creator=5082a85c489be6aa0f2e6693bf09cc1bbd35e988
301+
// - data=000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000225472616e73616374696f6e207375636365737366756c6c792076657269666965642e000000000000000000000000000000000000000000000000000000000000
302+
// - topic[0]=3f3cfdb26fb5f9f1786ab4f1a1f9cd4c0b5e726cbdfc26e495261731aad44e39
299303
// gas irOptimized: 127916
300304
// gas legacy: 130571
301305
// gas legacyOptimized: 100147

test/libsolidity/semanticTests/structs/event.sol

+4
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ contract C {
1515
// ----
1616
// library: L
1717
// f() ->
18+
// - log[0]
19+
// - creator=5082a85c489be6aa0f2e6693bf09cc1bbd35e988
20+
// - data=0000000000000000000000000000000000000000000000000000000000000001
21+
// - topic[0]=d8995181daeaf0ad90300384c4cef95adc251321ff8e5194f1e64733dcbd2746

test/libsolidity/semanticTests/viaYul/erc20.sol

+18
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,25 @@ contract ERC20 {
9898
// ----
9999
// totalSupply() -> 20
100100
// transfer(address,uint256): 2, 5 -> true
101+
// - log[0]
102+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
103+
// - data=0000000000000000000000000000000000000000000000000000000000000005
104+
// - topic[0]=ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
105+
// - topic[1]=0000000000000000000000001212121212121212121212121212120000000012
106+
// - topic[2]=0000000000000000000000000000000000000000000000000000000000000002
101107
// decreaseAllowance(address,uint256): 2, 0 -> true
108+
// - log[0]
109+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
110+
// - data=0000000000000000000000000000000000000000000000000000000000000000
111+
// - topic[0]=8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925
112+
// - topic[1]=0000000000000000000000001212121212121212121212121212120000000012
113+
// - topic[2]=0000000000000000000000000000000000000000000000000000000000000002
102114
// decreaseAllowance(address,uint256): 2, 1 -> FAILURE, hex"4e487b71", 0x11
103115
// transfer(address,uint256): 2, 14 -> true
116+
// - log[0]
117+
// - creator=0fdd67305928fcac8d213d1e47bfa6165cd0b87b
118+
// - data=000000000000000000000000000000000000000000000000000000000000000e
119+
// - topic[0]=ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
120+
// - topic[1]=0000000000000000000000001212121212121212121212121212120000000012
121+
// - topic[2]=0000000000000000000000000000000000000000000000000000000000000002
104122
// transfer(address,uint256): 2, 2 -> FAILURE, hex"4e487b71", 0x11

test/libsolidity/util/SoltestTypes.h

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

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

0 commit comments

Comments
 (0)