Ethereum  PoC-8
The C++ Implementation of Ethereum
LogFilter.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
22 #include "LogFilter.h"
23 
24 #include <libdevcore/SHA3.h>
25 #include "Block.h"
26 using namespace std;
27 using namespace dev;
28 using namespace dev::eth;
29 
30 std::ostream& dev::eth::operator<<(std::ostream& _out, LogFilter const& _s)
31 {
32  // TODO
33  _out << "(@" << _s.m_addresses << "#" << _s.m_topics << ">" << _s.m_earliest << "-" << _s.m_latest << "< )";
34  return _out;
35 }
36 
37 void LogFilter::streamRLP(RLPStream& _s) const
38 {
39  _s.appendList(4) << m_addresses << m_topics << m_earliest << m_latest;
40 }
41 
43 {
44  RLPStream s;
45  streamRLP(s);
46  return dev::sha3(s.out());
47 }
48 
49 bool LogFilter::isRangeFilter() const
50 {
51  if (m_addresses.size())
52  return false;
53 
54  for (auto const& t: m_topics)
55  if (t.size())
56  return false;
57 
58  return true;
59 }
60 
61 bool LogFilter::matches(LogBloom _bloom) const
62 {
63  if (m_addresses.size())
64  {
65  for (auto const& i: m_addresses)
66  if (_bloom.containsBloom<3>(dev::sha3(i)))
67  goto OK1;
68  return false;
69  }
70  OK1:
71  for (auto const& t: m_topics)
72  if (t.size())
73  {
74  for (auto const& i: t)
75  if (_bloom.containsBloom<3>(dev::sha3(i)))
76  goto OK2;
77  return false;
78  OK2:;
79  }
80  return true;
81 }
82 
83 bool LogFilter::matches(Block const& _s, unsigned _i) const
84 {
85  return matches(_s.receipt(_i)).size() > 0;
86 }
87 
88 vector<LogBloom> LogFilter::bloomPossibilities() const
89 {
90  // return combination of each of the addresses/topics
91  vector<LogBloom> ret;
92 
93  // | every address with every topic
94  for (auto const& i: m_addresses)
95  {
96  // 1st case, there are addresses and topics
97  //
98  // m_addresses = [a0, a1];
99  // m_topics = [[t0], [t1a, t1b], [], []];
100  //
101  // blooms = [
102  // a0 | t0, a0 | t1a | t1b,
103  // a1 | t0, a1 | t1a | t1b
104  // ]
105  //
106  for (auto const& t: m_topics)
107  if (t.size())
108  {
109  LogBloom b = LogBloom().shiftBloom<3>(dev::sha3(i));
110  for (auto const &j: t)
111  b = b.shiftBloom<3>(dev::sha3(j));
112  ret.push_back(b);
113  }
114  }
115 
116  // 2nd case, there are no topics
117  //
118  // m_addresses = [a0, a1];
119  // m_topics = [[t0], [t1a, t1b], [], []];
120  //
121  // blooms = [a0, a1];
122  //
123  if (!ret.size())
124  for (auto const& i: m_addresses)
125  ret.push_back(LogBloom().shiftBloom<3>(dev::sha3(i)));
126 
127  // 3rd case, there are no addresses, at least create blooms from topics
128  //
129  // m_addresses = [];
130  // m_topics = [[t0], [t1a, t1b], [], []];
131  //
132  // blooms = [t0, t1a | t1b];
133  //
134  if (!m_addresses.size())
135  for (auto const& t: m_topics)
136  if (t.size())
137  {
138  LogBloom b;
139  for (auto const &j: t)
140  b = b.shiftBloom<3>(dev::sha3(j));
141  ret.push_back(b);
142  }
143 
144  return ret;
145 }
146 
147 LogEntries LogFilter::matches(TransactionReceipt const& _m) const
148 {
149  // there are no addresses or topics to filter
150  if (isRangeFilter())
151  return _m.log();
152 
153  LogEntries ret;
154  if (matches(_m.bloom()))
155  for (LogEntry const& e: _m.log())
156  {
157  if (!m_addresses.empty() && !m_addresses.count(e.address))
158  goto continue2;
159  for (unsigned i = 0; i < 4; ++i)
160  if (!m_topics[i].empty() && (e.topics.size() < i || !m_topics[i].count(e.topics[i])))
161  goto continue2;
162  ret.push_back(e);
163  continue2:;
164  }
165  return ret;
166 }
dev::FixedHash::shiftBloom
FixedHash & shiftBloom(FixedHash< M > const &_h)
Definition: FixedHash.h:175
dev::eth::LogFilter
Definition: LogFilter.h:51
dev::sha3
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
dev::RLPStream::out
bytes const & out() const
Read the byte stream.
Definition: RLP.h:419
dev::eth
Definition: BasicAuthority.h:32
dev::FixedHash< 32 >
dev::FixedHash::containsBloom
bool containsBloom(FixedHash< M > const &_h)
Definition: FixedHash.h:180
dev::eth::LogBloom
h2048 LogBloom
The log bloom's size (2048-bit).
Definition: Common.h:50
Block.h
dev::eth::LogEntries
std::vector< LogEntry > LogEntries
Definition: LogEntry.h:51
SHA3.h
dev::eth::LogEntry
Definition: LogEntry.h:35
dev::RLPStream
Class for writing to an RLP bytestream.
Definition: RLP.h:370
dev::eth::Block::receipt
TransactionReceipt const & receipt(unsigned _i) const
Get the transaction receipt for the transaction of the given index.
Definition: Block.h:189
std
Definition: FixedHash.h:393
dev::eth::operator<<
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:217
dev::eth::TransactionReceipt::log
LogEntries const & log() const
Definition: TransactionReceipt.h:56
dev::eth::TransactionReceipt
Definition: TransactionReceipt.h:40
dev
Definition: Address.cpp:21
LogFilter.h
dev::eth::TransactionReceipt::bloom
LogBloom const & bloom() const
Definition: TransactionReceipt.h:55
dev::eth::Block
Active model of a block within the block chain. Keeps track of all transactions, receipts and state f...
Definition: Block.h:69
dev::RLPStream::appendList
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:268