Browse Source

filters using blockHashes instead of blockNumbers

cl-refactor
Marek Kotewicz 10 years ago
parent
commit
1108680fe3
  1. 4
      libethcore/Common.h
  2. 4
      libethereum/Client.cpp
  3. 29
      libethereum/ClientBase.cpp
  4. 2
      libethereum/ClientBase.h
  5. 2
      libethereum/Interface.h
  6. 27
      libethereum/LogFilter.cpp
  7. 15
      libethereum/LogFilter.h
  8. 4
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  9. 2
      mix/MixClient.cpp

4
libethcore/Common.h

@ -77,6 +77,10 @@ using BlockNumber = unsigned;
static const BlockNumber LatestBlock = (BlockNumber)-2; static const BlockNumber LatestBlock = (BlockNumber)-2;
static const BlockNumber PendingBlock = (BlockNumber)-1; static const BlockNumber PendingBlock = (BlockNumber)-1;
static const h256 LatestBlockHash = h256(2);
static const h256 EarliestBlockHash = h256(1);
static const h256 PendingBlockHash = h256(0);
enum class RelativeBlock: BlockNumber enum class RelativeBlock: BlockNumber
{ {

4
libethereum/Client.cpp

@ -337,7 +337,7 @@ void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash&
{ {
Guard l(x_filtersWatches); Guard l(x_filtersWatches);
for (pair<h256 const, InstalledFilter>& i: m_filters) for (pair<h256 const, InstalledFilter>& i: m_filters)
if (i.second.filter.envelops(RelativeBlock::Pending, m_bc.number() + 1)) if (isInBlockHashRange(i.second.filter.earliest(), i.second.filter.latest(), PendingBlockHash))
{ {
// acceptable number. // acceptable number.
auto m = i.second.filter.matches(_receipt); auto m = i.second.filter.matches(_receipt);
@ -359,7 +359,7 @@ void Client::appendFromNewBlock(h256 const& _block, h256Hash& io_changed)
Guard l(x_filtersWatches); Guard l(x_filtersWatches);
for (pair<h256 const, InstalledFilter>& i: m_filters) for (pair<h256 const, InstalledFilter>& i: m_filters)
if (i.second.filter.envelops(RelativeBlock::Latest, d.number) && i.second.filter.matches(d.logBloom)) if (isInBlockHashRange(i.second.filter.earliest(), i.second.filter.latest(), d.hash()) && i.second.filter.matches(d.logBloom))
// acceptable number & looks like block may contain a matching log entry. // acceptable number & looks like block may contain a matching log entry.
for (size_t j = 0; j < br.receipts.size(); j++) for (size_t j = 0; j < br.receipts.size(); j++)
{ {

29
libethereum/ClientBase.cpp

@ -171,8 +171,8 @@ LocalisedLogEntries ClientBase::logs(unsigned _watchId) const
LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const
{ {
LocalisedLogEntries ret; LocalisedLogEntries ret;
unsigned begin = min<unsigned>(bc().number() + 1, (unsigned)_f.latest()); unsigned begin = min<unsigned>(bc().number() + 1, (unsigned)numberFromHash(_f.latest()));
unsigned end = min(bc().number(), min(begin, (unsigned)_f.earliest())); unsigned end = min(bc().number(), min(begin, (unsigned)numberFromHash(_f.earliest())));
// Handle pending transactions differently as they're not on the block chain. // Handle pending transactions differently as they're not on the block chain.
if (begin > bc().number()) if (begin > bc().number())
@ -442,6 +442,31 @@ h256 ClientBase::hashFromNumber(BlockNumber _number) const
BlockNumber ClientBase::numberFromHash(h256 _blockHash) const BlockNumber ClientBase::numberFromHash(h256 _blockHash) const
{ {
if (_blockHash == PendingBlockHash)
_blockHash = hashFromNumber(PendingBlock);
else if (_blockHash == LatestBlockHash)
_blockHash = hashFromNumber(LatestBlock);
else if (_blockHash == EarliestBlockHash)
_blockHash = hashFromNumber(0);
return bc().number(_blockHash); return bc().number(_blockHash);
} }
int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const
{
BlockNumber n1 = numberFromHash(_h1);
BlockNumber n2 = numberFromHash(_h2);
if (n1 > n2) {
return 1;
} else if (n1 == n2) {
return 0;
}
return -1;
}
bool ClientBase::isInBlockHashRange(h256 _from, h256 _to, h256 _q) const
{
int c1 = compareBlockHashes(_from, _q);
int c2 = compareBlockHashes(_q, _to);
return (c1 == 0 || c1 == -1) && (c2 == 0 || c2 == -1);
}

2
libethereum/ClientBase.h

@ -117,6 +117,8 @@ public:
virtual h256 hashFromNumber(BlockNumber _number) const override; virtual h256 hashFromNumber(BlockNumber _number) const override;
virtual BlockNumber numberFromHash(h256 _blockHash) const override; virtual BlockNumber numberFromHash(h256 _blockHash) const override;
virtual int compareBlockHashes(h256 _h1, h256 _h2) const override;
virtual bool isInBlockHashRange(h256 _from, h256 _to, h256 _q) const override;
virtual BlockInfo blockInfo(h256 _hash) const override; virtual BlockInfo blockInfo(h256 _hash) const override;
virtual BlockDetails blockDetails(h256 _hash) const override; virtual BlockDetails blockDetails(h256 _hash) const override;
virtual Transaction transaction(h256 _transactionHash) const override; virtual Transaction transaction(h256 _transactionHash) const override;

2
libethereum/Interface.h

@ -137,6 +137,8 @@ public:
virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const = 0; virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const = 0;
virtual h256 hashFromNumber(BlockNumber _number) const = 0; virtual h256 hashFromNumber(BlockNumber _number) const = 0;
virtual BlockNumber numberFromHash(h256 _blockHash) const = 0; virtual BlockNumber numberFromHash(h256 _blockHash) const = 0;
virtual int compareBlockHashes(h256 _h1, h256 _h2) const = 0;
virtual bool isInBlockHashRange(h256 _from, h256 _to, h256 _q) const = 0;
virtual BlockInfo blockInfo(h256 _hash) const = 0; virtual BlockInfo blockInfo(h256 _hash) const = 0;
virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual BlockDetails blockDetails(h256 _hash) const = 0;

27
libethereum/LogFilter.cpp

@ -46,33 +46,6 @@ h256 LogFilter::sha3() const
return dev::sha3(s.out()); return dev::sha3(s.out());
} }
static bool isNoLater(RelativeBlock _logBlockRelation, u256 _logBlockNumber, unsigned _latest)
{
if (_latest == PendingBlock)
return true;
else if (_latest == LatestBlock)
return _logBlockRelation == RelativeBlock::Latest;
else
return _logBlockNumber <= _latest;
}
static bool isNoEarlier(RelativeBlock _logBlockRelation, u256 _logBlockNumber, unsigned _earliest)
{
if (_earliest == PendingBlock)
return _logBlockRelation == RelativeBlock::Pending;
else if (_earliest == LatestBlock)
return true;
else
return _logBlockNumber >= _earliest;
}
bool LogFilter::envelops(RelativeBlock _logBlockRelation, u256 _logBlockNumber) const
{
return
isNoLater(_logBlockRelation, _logBlockNumber, m_latest) &&
isNoEarlier(_logBlockRelation, _logBlockNumber, m_earliest);
}
bool LogFilter::matches(LogBloom _bloom) const bool LogFilter::matches(LogBloom _bloom) const
{ {
if (m_addresses.size()) if (m_addresses.size())

15
libethereum/LogFilter.h

@ -45,15 +45,14 @@ class State;
class LogFilter class LogFilter
{ {
public: public:
LogFilter(unsigned _earliest = 0, unsigned _latest = PendingBlock): m_earliest(_earliest), m_latest(_latest) {} LogFilter(h256 _earliest = EarliestBlockHash, h256 _latest = PendingBlockHash): m_earliest(_earliest), m_latest(_latest) {}
void streamRLP(RLPStream& _s) const; void streamRLP(RLPStream& _s) const;
h256 sha3() const; h256 sha3() const;
unsigned earliest() const { return m_earliest; } h256 earliest() const { return m_earliest; }
unsigned latest() const { return m_latest; } h256 latest() const { return m_latest; }
bool envelops(RelativeBlock _logBlockRelation, u256 _logBlockNumber) const;
std::vector<LogBloom> bloomPossibilities() const; std::vector<LogBloom> bloomPossibilities() const;
bool matches(LogBloom _bloom) const; bool matches(LogBloom _bloom) const;
bool matches(State const& _s, unsigned _i) const; bool matches(State const& _s, unsigned _i) const;
@ -61,16 +60,16 @@ public:
LogFilter address(Address _a) { m_addresses.insert(_a); return *this; } 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 topic(unsigned _index, h256 const& _t) { if (_index < 4) m_topics[_index].insert(_t); return *this; }
LogFilter withEarliest(int _e) { m_earliest = _e; return *this; } LogFilter withEarliest(h256 _e) { m_earliest = _e; return *this; }
LogFilter withLatest(int _e) { m_latest = _e; return *this; } LogFilter withLatest(h256 _e) { m_latest = _e; return *this; }
friend std::ostream& dev::eth::operator<<(std::ostream& _out, dev::eth::LogFilter const& _s); friend std::ostream& dev::eth::operator<<(std::ostream& _out, dev::eth::LogFilter const& _s);
private: private:
AddressHash m_addresses; AddressHash m_addresses;
std::array<h256Hash, 4> m_topics; std::array<h256Hash, 4> m_topics;
unsigned m_earliest = 0; h256 m_earliest = EarliestBlockHash;
unsigned m_latest = LatestBlock; h256 m_latest = PendingBlockHash;
}; };
} }

4
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -201,9 +201,9 @@ static dev::eth::LogFilter toLogFilter(Json::Value const& _json) // commented to
// check only !empty. it should throw exceptions if input params are incorrect // check only !empty. it should throw exceptions if input params are incorrect
if (!_json["fromBlock"].empty()) if (!_json["fromBlock"].empty())
filter.withEarliest(jsToBlockNumber(_json["fromBlock"].asString())); filter.withEarliest(jsToFixed<32>(_json["fromBlock"].asString()));
if (!_json["toBlock"].empty()) if (!_json["toBlock"].empty())
filter.withLatest(jsToBlockNumber(_json["toBlock"].asString())); filter.withLatest(jsToFixed<32>(_json["toBlock"].asString()));
if (!_json["address"].empty()) if (!_json["address"].empty())
{ {
if (_json["address"].isArray()) if (_json["address"].isArray())

2
mix/MixClient.cpp

@ -251,7 +251,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
h256Set changed; h256Set changed;
Guard l(x_filtersWatches); Guard l(x_filtersWatches);
for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters) for (std::pair<h256 const, eth::InstalledFilter>& i: m_filters)
if ((unsigned)i.second.filter.latest() > bc().number()) if (compareBlockHashes(i.second.filter.latest(), bc().currentHash()) > 0)
{ {
// acceptable number. // acceptable number.
auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1)); auto m = i.second.filter.matches(_state.receipt(_state.pending().size() - 1));

Loading…
Cancel
Save