From d692c959c79d47a3f37feebb70ee4c0d8c7c41ec Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 15 Jul 2015 12:26:04 +0200 Subject: [PATCH] fixed anonymous logs --- libethereum/ClientBase.cpp | 49 +++++++++++++++++++++++++------------- libethereum/LogFilter.cpp | 16 +++++++++++++ libethereum/LogFilter.h | 10 ++++++++ 3 files changed, 59 insertions(+), 16 deletions(-) diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 4f913304d..fb81c2592 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -177,16 +177,8 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const begin = bc().number(); } - // Handle blocks from main chain - set matchingBlocks; - for (auto const& i: _f.bloomPossibilities()) - for (auto u: bc().withBlockBloom(i, end, begin)) - matchingBlocks.insert(u); - - for (auto n: matchingBlocks) - appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); - // Handle reverted blocks + // There are not so many, so let's iterate over them h256s blocks; h256 ancestor; unsigned ancestorIndex; @@ -195,6 +187,34 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const for (size_t i = 0; i < ancestorIndex; i++) appendLogsFromBlock(_f, blocks[i], BlockPolarity::Dead, ret); + // cause end is our earliest block, let's compare it with our ancestor + // if ancestor is smaller let's move our end to it + // example: + // + // 3b -> 2b -> 1b + // -> g + // 3a -> 2a -> 1a + // + // if earliest is at 1a and latest is a 3b, coverting them to numbers + // will give us pair (1, 3) + // and we want to get all logs from g (ancestor) to 3 + // so we have to move 1a to g + end = min(end, (unsigned)numberFromHash(ancestor)); + + // Handle blocks from main chain + set matchingBlocks; + if (!_f.isRangeFilter()) + for (auto const& i: _f.bloomPossibilities()) + for (auto u: bc().withBlockBloom(i, end, begin)) + matchingBlocks.insert(u); + else + // if it is a range filter, we want to get all logs from all blocks in given range + for (unsigned i = end; i <= begin; i++) + matchingBlocks.insert(i); + + for (auto n: matchingBlocks) + appendLogsFromBlock(_f, bc().numberHash(n), BlockPolarity::Live, ret); + return ret; } @@ -204,13 +224,10 @@ void ClientBase::appendLogsFromBlock(LogFilter const& _f, h256 const& _blockHash for (size_t i = 0; i < receipts.size(); i++) { TransactionReceipt receipt = receipts[i]; - if (_f.matches(receipt.bloom())) - { - auto th = transaction(_blockHash, i).sha3(); - LogEntries le = _f.matches(receipt); - for (unsigned j = 0; j < le.size(); ++j) - io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); - } + auto th = transaction(_blockHash, i).sha3(); + LogEntries le = _f.matches(receipt); + for (unsigned j = 0; j < le.size(); ++j) + io_logs.insert(io_logs.begin(), LocalisedLogEntry(le[j], _blockHash, (BlockNumber)bc().number(_blockHash), th, i, 0, _polarity)); } } diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index 029869c7a..95c07f2a3 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -46,6 +46,18 @@ h256 LogFilter::sha3() const return dev::sha3(s.out()); } +bool LogFilter::isRangeFilter() const +{ + if (m_addresses.size()) + return false; + + for (auto const& t: m_topics) + if (t.size()) + return false; + + return true; +} + bool LogFilter::matches(LogBloom _bloom) const { if (m_addresses.size()) @@ -134,6 +146,10 @@ vector LogFilter::bloomPossibilities() const LogEntries LogFilter::matches(TransactionReceipt const& _m) const { + // there are no addresses or topics to filter + if (isRangeFilter()) + return _m.log(); + LogEntries ret; if (matches(_m.bloom())) for (LogEntry const& e: _m.log()) diff --git a/libethereum/LogFilter.h b/libethereum/LogFilter.h index ff33346f8..092f173ef 100644 --- a/libethereum/LogFilter.h +++ b/libethereum/LogFilter.h @@ -50,10 +50,20 @@ public: void streamRLP(RLPStream& _s) const; h256 sha3() const; + /// hash of earliest block which should be filtered h256 earliest() const { return m_earliest; } + + /// hash of latest block which should be filtered h256 latest() const { return m_latest; } + /// Range filter is a filter which doesn't care about addresses or topics + /// Matches are all entries from earliest to latest + /// @returns true if addresses and topics are unspecified + bool isRangeFilter() const; + + /// @returns bloom possibilities for all addresses and topics std::vector bloomPossibilities() const; + bool matches(LogBloom _bloom) const; bool matches(State const& _s, unsigned _i) const; LogEntries matches(TransactionReceipt const& _r) const;