Fabcoin Core  0.16.2
P2P Digital Currency
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  {
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 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
LogBloom const & bloom() const
std::ostream & operator<<(std::ostream &_out, BlockHeader const &_bi)
Definition: BlockHeader.h:194
bytes const & out() const
Read the byte stream.
Definition: RLP.h:433
std::hash for asio::adress
Definition: Common.h:323
FixedHash & shiftBloom(FixedHash< M > const &_h)
Definition: FixedHash.h:170
TransactionReceipt const & receipt(unsigned _i) const
Get the transaction receipt for the transaction of the given index.
Definition: Block.h:194
bool containsBloom(FixedHash< M > const &_h)
Definition: FixedHash.h:175
Active model of a block within the block chain.
Definition: Block.h:73
RLPStream & appendList(size_t _items)
Appends a list.
Definition: RLP.cpp:276
#define b(i, j)
AddressHash m_addresses
Definition: LogFilter.h:84
std::array< h256Hash, 4 > m_topics
Definition: LogFilter.h:85
uint8_t const size_t const size
Definition: sha3.h:20
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
#define e(i)
Definition: sha.cpp:733
h2048 LogBloom
The log bloom&#39;s size (2048-bit).
Definition: Common.h:58
Class for writing to an RLP bytestream.
Definition: RLP.h:383
std::vector< LogEntry > LogEntries
Definition: ExtVMFace.h:110
LogEntries const & log() const
Definition: ExtVMFace.h:88