Browse Source

Remove skip & max, integrate new heirarchical bloom stuff with everything

else.
cl-refactor
Gav Wood 10 years ago
parent
commit
c1e71dae80
  1. 12
      alethzero/MainWin.cpp
  2. 6
      libdevcore/FixedHash.h
  3. 40
      libethereum/BlockChain.cpp
  4. 2
      libethereum/BlockDetails.h
  5. 69
      libethereum/Client.cpp
  6. 14
      libethereum/LogFilter.cpp
  7. 10
      libethereum/LogFilter.h
  8. 4
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  9. 12
      mix/MixClient.cpp

12
alethzero/MainWin.cpp

@ -1012,15 +1012,17 @@ void Main::refreshBlockChain()
h256 h(f.toStdString());
if (bc.isKnown(h))
blocks.insert(h);
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3, 32>(sha3(h)), 0, -1))
blocks.insert(bc.numberHash(b));
}
else if (f.toLongLong() <= bc.number())
blocks.insert(bc.numberHash(u256(f.toLongLong())));
/*else if (f.size() == 40)
else if (f.size() == 40)
{
Address h(f[0]);
if (bc.(h))
blocks.insert(h);
}*/
Address h(f.toStdString());
for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3, 32>(sha3(h)), 0, -1))
blocks.insert(bc.numberHash(b));
}
QByteArray oldSelected = ui->blocks->count() ? ui->blocks->currentItem()->data(Qt::UserRole).toByteArray() : QByteArray();
ui->blocks->clear();

6
libdevcore/FixedHash.h

@ -156,15 +156,15 @@ public:
template <unsigned P, unsigned M> inline FixedHash& shiftBloom(FixedHash<M> const& _h)
{
return (*this |= _h.template nbloom<P, N>());
return (*this |= _h.template bloom<P, N>());
}
template <unsigned P, unsigned M> inline bool containsBloom(FixedHash<M> const& _h)
{
return contains(_h.template nbloom<P, N>());
return contains(_h.template bloom<P, N>());
}
template <unsigned P, unsigned M> inline FixedHash<M> nbloom() const
template <unsigned P, unsigned M> inline FixedHash<M> bloom() const
{
static const unsigned c_bloomBits = M * 8;
unsigned mask = c_bloomBits - 1;

40
libethereum/BlockChain.cpp

@ -610,15 +610,26 @@ static inline unsigned ceilDiv(unsigned n, unsigned d) { return n / (n + d - 1);
static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); }
static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); }
// Level 1
// [xxx. ]
// Level 0
// [.x............F.]
// [........x.......]
// [T.............x.]
// [............ ]
// F = 14. T = 32
vector<unsigned> BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest) const
{
vector<unsigned> ret;
// start from the top-level
unsigned u = upow(c_bloomIndexSize, c_bloomIndexLevels - 1);
unsigned u = upow(c_bloomIndexSize, c_bloomIndexLevels);
// run through each of the top-level blockbloom blocks
for (unsigned index = _earliest / u; index < ceilDiv(_latest, u); ++index)
for (unsigned index = _earliest / u; index <= ceilDiv(_latest, u); ++index) // 0
ret += withBlockBloom(_b, _earliest, _latest, c_bloomIndexLevels - 1, index);
return ret;
@ -626,12 +637,33 @@ vector<unsigned> BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earlie
vector<unsigned> BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earliest, unsigned _latest, unsigned _level, unsigned _index) const
{
// 14, 32, 1, 0
// 14, 32, 0, 0
// 14, 32, 0, 1
// 14, 32, 0, 2
vector<unsigned> ret;
// unsigned u = upow(c_bloomIndexSize, _level);
unsigned uCourse = upow(c_bloomIndexSize, _level + 1);
// 256
// 16
unsigned uFine = upow(c_bloomIndexSize, _level);
// 16
// 1
unsigned obegin = _index == _earliest / uCourse ? _earliest / uFine % c_bloomIndexSize : 0;
// 0
// 14
// 0
// 0
unsigned oend = _index == _latest / uCourse ? (_latest / uFine) % c_bloomIndexSize + 1 : c_bloomIndexSize;
// 3
// 16
// 16
// 1
BlocksBlooms bb = blocksBlooms(_level, _index);
for (unsigned o = 0; o < 256; ++o) // TODO: crop.
for (unsigned o = obegin; o < oend; ++o)
if (bb.blooms[o].contains(_b))
{
// This level has something like what we want.

2
libethereum/BlockDetails.h

@ -39,7 +39,7 @@ namespace eth
// TODO: OPTIMISE: constructors take bytes, RLP used only in necessary classes.
static const unsigned c_bloomIndexSize = 16;
static const unsigned c_bloomIndexLevels = 6;
static const unsigned c_bloomIndexLevels = 2;
struct BlockDetails
{

69
libethereum/Client.cpp

@ -833,8 +833,6 @@ LocalisedLogEntries Client::logs(LogFilter const& _f) const
LocalisedLogEntries ret;
unsigned begin = min<unsigned>(m_bc.number() + 1, (unsigned)_f.latest());
unsigned end = min(m_bc.number(), min(begin, (unsigned)_f.earliest()));
unsigned m = _f.max();
unsigned s = _f.skip();
// Handle pending transactions differently as they're not on the block chain.
if (begin > m_bc.number())
@ -847,71 +845,52 @@ LocalisedLogEntries Client::logs(LogFilter const& _f) const
auto sha3 = m_postMine.pending()[i].sha3();
LogEntries le = _f.matches(tr);
if (le.size())
{
for (unsigned j = 0; j < le.size() && ret.size() != m; ++j)
if (s)
s--;
else
ret.insert(ret.begin(), LocalisedLogEntry(le[j], begin, sha3));
}
for (unsigned j = 0; j < le.size(); ++j)
ret.insert(ret.begin(), LocalisedLogEntry(le[j], begin, sha3));
}
begin = m_bc.number();
}
set<unsigned> matchingBlocks;
for (auto const& i: _f.bloomPossibilities())
for (auto u: m_bc.withBlockBloom(i, end, begin))
matchingBlocks.insert(u);
#if ETH_DEBUG
// fill these params
unsigned skipped = 0;
unsigned falsePos = 0;
#endif
auto h = m_bc.numberHash(begin);
unsigned n = begin;
for (; ret.size() != m && n != end; n--, h = m_bc.details(h).parent)
for (auto n: matchingBlocks)
{
#if ETH_DEBUG
int total = 0;
#endif
// check block bloom
auto blockBloom = m_bc.blockBloom(n);
if (_f.matches(blockBloom))
auto h = m_bc.numberHash(n);
auto receipts = m_bc.receipts(h).receipts;
for (size_t i = 0; i < receipts.size(); i++)
{
auto receipts = m_bc.receipts(h).receipts;
for (size_t i = 0; i < receipts.size(); i++)
TransactionReceipt receipt = receipts[i];
if (_f.matches(receipt.bloom()))
{
TransactionReceipt receipt = receipts[i];
if (_f.matches(receipt.bloom()))
auto info = m_bc.info(h);
auto h = transaction(info.hash, i).sha3();
LogEntries le = _f.matches(receipt);
if (le.size())
{
auto info = m_bc.info(h);
auto h = transaction(info.hash, i).sha3();
LogEntries le = _f.matches(receipt);
if (le.size())
{
#if ETH_DEBUG
total += le.size();
total += le.size();
#endif
for (unsigned j = 0; j < le.size() && ret.size() != m; ++j)
{
if (s)
s--;
else
ret.insert(ret.begin(), LocalisedLogEntry(le[j], n, h));
}
}
for (unsigned j = 0; j < le.size(); ++j)
ret.insert(ret.begin(), LocalisedLogEntry(le[j], n, h));
}
#if ETH_DEBUG
if (!total)
falsePos++;
#endif
}
#if ETH_DEBUG
}
else
skipped++;
if (!total)
falsePos++;
#endif
if (n == end)
break;
}
}
#if ETH_DEBUG
cdebug << (begin - n) << "searched; " << skipped << "skipped; " << falsePos << "false +ves";
cdebug << matchingBlocks.size() << "searched from" << (end - begin) << "skipped; " << falsePos << "false +ves";
#endif
return ret;
}

14
libethereum/LogFilter.cpp

@ -30,13 +30,13 @@ using namespace dev::eth;
std::ostream& dev::eth::operator<<(std::ostream& _out, LogFilter const& _s)
{
// TODO
_out << "(@" << _s.m_addresses << "#" << _s.m_topics << ">" << _s.m_earliest << "-" << _s.m_latest << "< +" << _s.m_skip << "^" << _s.m_max << ")";
_out << "(@" << _s.m_addresses << "#" << _s.m_topics << ">" << _s.m_earliest << "-" << _s.m_latest << "< )";
return _out;
}
void LogFilter::streamRLP(RLPStream& _s) const
{
_s.appendList(6) << m_addresses << m_topics << m_earliest << m_latest << m_max << m_skip;
_s.appendList(4) << m_addresses << m_topics << m_earliest << m_latest;
}
h256 LogFilter::sha3() const
@ -73,6 +73,16 @@ bool LogFilter::matches(State const& _s, unsigned _i) const
return matches(_s.receipt(_i)).size() > 0;
}
vector<LogBloom> LogFilter::bloomPossibilities() const
{
// return combination of each of the addresses/topics
vector<LogBloom> ret;
// TODO proper combinatorics.
for (auto i: m_addresses)
ret.push_back(LogBloom().shiftBloom<3, 32>(dev::sha3(i)));
return ret;
}
LogEntries LogFilter::matches(TransactionReceipt const& _m) const
{
LogEntries ret;

10
libethereum/LogFilter.h

@ -45,23 +45,21 @@ class State;
class LogFilter
{
public:
LogFilter(int _earliest = 0, int _latest = -1, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {}
LogFilter(int _earliest = 0, int _latest = -1): m_earliest(_earliest), m_latest(_latest) {}
void streamRLP(RLPStream& _s) const;
h256 sha3() const;
int earliest() const { return m_earliest; }
int latest() const { return m_latest; }
unsigned max() const { return m_max; }
unsigned skip() const { return m_skip; }
std::vector<LogBloom> bloomPossibilities() const;
bool matches(LogBloom _bloom) const;
bool matches(State const& _s, unsigned _i) const;
LogEntries matches(TransactionReceipt const& _r) const;
LogFilter address(Address _a) { m_addresses.insert(_a); return *this; }
LogFilter topic(unsigned _index, h256 const& _t) { if (_index < 4) m_topics[_index].insert(_t); return *this; }
LogFilter withMax(unsigned _m) { m_max = _m; return *this; }
LogFilter withSkip(unsigned _m) { m_skip = _m; return *this; }
LogFilter withEarliest(int _e) { m_earliest = _e; return *this; }
LogFilter withLatest(int _e) { m_latest = _e; return *this; }
@ -72,8 +70,6 @@ private:
std::array<h256Set, 4> m_topics;
int m_earliest = 0;
int m_latest = -1;
unsigned m_max = 10;
unsigned m_skip = 0;
};
}

4
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -128,10 +128,6 @@ static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to
filter.withEarliest(_json["earliest"].asInt());
if (_json["latest"].isInt())
filter.withLatest(_json["lastest"].asInt());
if (_json["max"].isInt())
filter.withMax(_json["max"].asInt());
if (_json["skip"].isInt())
filter.withSkip(_json["skip"].asInt());
if (!_json["address"].empty())
{
if (_json["address"].isArray())

12
mix/MixClient.cpp

@ -331,7 +331,6 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
unsigned lastBlock = bc().number();
unsigned block = std::min<unsigned>(lastBlock, (unsigned)_f.latest());
unsigned end = std::min(lastBlock, std::min(block, (unsigned)_f.earliest()));
unsigned skip = _f.skip();
// Pending transactions
if (block > bc().number())
{
@ -341,9 +340,8 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
// Might have a transaction that contains a matching log.
TransactionReceipt const& tr = m_state.receipt(i);
LogEntries logEntries = _f.matches(tr);
for (unsigned entry = 0; entry < logEntries.size() && ret.size() != _f.max(); ++entry)
for (unsigned entry = 0; entry < logEntries.size(); ++entry)
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
}
block = bc().number();
}
@ -355,12 +353,8 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const
if (_f.matches(bc().info(h).logBloom))
for (TransactionReceipt receipt: bc().receipts(h).receipts)
if (_f.matches(receipt.bloom()))
{
LogEntries logEntries = _f.matches(receipt);
for (unsigned entry = skip; entry < logEntries.size() && ret.size() != _f.max(); ++entry)
ret.insert(ret.begin(), LocalisedLogEntry(logEntries[entry], block));
skip -= std::min(skip, static_cast<unsigned>(logEntries.size()));
}
for (auto const& e: _f.matches(receipt))
ret.insert(ret.begin(), LocalisedLogEntry(e, block));
h = bc().details(h).parent;
}
return ret;

Loading…
Cancel
Save