Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #2108 from debris/filter_blockHash
Browse files Browse the repository at this point in the history
json-rpc update
  • Loading branch information
Gav Wood committed Jun 11, 2015
2 parents f7e04de + 6d75a52 commit 413848c
Show file tree
Hide file tree
Showing 16 changed files with 311 additions and 115 deletions.
4 changes: 4 additions & 0 deletions libethcore/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ using BlockNumber = unsigned;

static const BlockNumber LatestBlock = (BlockNumber)-2;
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
{
Expand Down
4 changes: 2 additions & 2 deletions libethereum/BlockChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -926,8 +926,8 @@ void BlockChain::checkConsistency()
delete it;
}

static inline unsigned upow(unsigned a, unsigned b) { while (b-- > 0) a *= a; return a; }
static inline unsigned ceilDiv(unsigned n, unsigned d) { return n / (n + d - 1); }
static inline unsigned upow(unsigned a, unsigned b) { if (!b) return 1; while (--b > 0) a *= a; return a; }
static inline unsigned ceilDiv(unsigned n, unsigned d) { return (n + d - 1) / d; }
//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)); }

Expand Down
1 change: 1 addition & 0 deletions libethereum/BlockChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ class BlockChain
BlockLogBlooms logBlooms() const { return logBlooms(currentHash()); }

/// Get the transactions' receipts of a block (or the most recent mined if none given). Thread-safe.
/// receipts are given in the same order are in the same order as the transactions
BlockReceipts receipts(h256 const& _hash) const { return queryExtras<BlockReceipts, ExtraReceipts>(_hash, m_receipts, x_receipts, NullBlockReceipts); }
BlockReceipts receipts() const { return receipts(currentHash()); }

Expand Down
78 changes: 41 additions & 37 deletions libethereum/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,21 +428,17 @@ void Client::killChain()

void Client::clearPending()
{
h256Hash changeds;
DEV_WRITE_GUARDED(x_postMine)
{
if (!m_postMine.pending().size())
return;
// for (unsigned i = 0; i < m_postMine.pending().size(); ++i)
// appendFromNewPending(m_postMine.logBloom(i), changeds);
changeds.insert(PendingChangedFilter);
m_tq.clear();
DEV_READ_GUARDED(x_preMine)
m_postMine = m_preMine;
}

startMining();

h256Hash changeds;
noteChanged(changeds);
}

Expand All @@ -465,47 +461,53 @@ static S& filtersStreamOut(S& _out, T const& _fs)
return _out;
}

void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& io_changed, h256 _transactionHash)
void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Hash& io_changed, h256 _sha3)
{
Guard l(x_filtersWatches);
io_changed.insert(PendingChangedFilter);
m_specialFilters.at(PendingChangedFilter).push_back(_sha3);
for (pair<h256 const, InstalledFilter>& i: m_filters)
if (i.second.filter.envelops(RelativeBlock::Pending, m_bc.number() + 1))
{
// acceptable number.
auto m = i.second.filter.matches(_receipt);
if (m.size())
{
// acceptable number.
auto m = i.second.filter.matches(_receipt);
if (m.size())
{
// filter catches them
for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, m_bc.number() + 1, _transactionHash));
io_changed.insert(i.first);
}
// filter catches them
for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l));
io_changed.insert(i.first);
}
}
}

void Client::appendFromNewBlock(h256 const& _block, h256Hash& io_changed)
{
// TODO: more precise check on whether the txs match.
auto d = m_bc.info(_block);
auto br = m_bc.receipts(_block);
auto receipts = m_bc.receipts(_block).receipts;

Guard l(x_filtersWatches);
io_changed.insert(ChainChangedFilter);
m_specialFilters.at(ChainChangedFilter).push_back(_block);
for (pair<h256 const, InstalledFilter>& i: m_filters)
if (i.second.filter.envelops(RelativeBlock::Latest, d.number) && i.second.filter.matches(d.logBloom))
// acceptable number & looks like block may contain a matching log entry.
for (size_t j = 0; j < br.receipts.size(); j++)
{
// acceptable number & looks like block may contain a matching log entry.
unsigned logIndex = 0;
for (size_t j = 0; j < receipts.size(); j++)
{
logIndex++;
auto tr = receipts[j];
auto m = i.second.filter.matches(tr);
if (m.size())
{
auto tr = br.receipts[j];
auto m = i.second.filter.matches(tr);
if (m.size())
{
auto transactionHash = transaction(d.hash(), j).sha3();
// filter catches them
for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, (unsigned)d.number, transactionHash));
io_changed.insert(i.first);
}
auto transactionHash = transaction(d.hash(), j).sha3();
// filter catches them
for (LogEntry const& l: m)
i.second.changes.push_back(LocalisedLogEntry(l, d, transactionHash, j, logIndex));
io_changed.insert(i.first);
}
}
}
}

void Client::setForceMining(bool _enable)
Expand Down Expand Up @@ -643,7 +645,7 @@ void Client::syncTransactionQueue()
DEV_READ_GUARDED(x_postMine)
for (size_t i = 0; i < newPendingReceipts.size(); i++)
appendFromNewPending(newPendingReceipts[i], changeds, m_postMine.pending()[i].sha3());
changeds.insert(PendingChangedFilter);


// Tell farm about new transaction (i.e. restartProofOfWork mining).
onPostStateChanged();
Expand Down Expand Up @@ -686,7 +688,6 @@ void Client::onChainChanged(ImportRoute const& _ir)
h256Hash changeds;
for (auto const& h: _ir.first)
appendFromNewBlock(h, changeds);
changeds.insert(ChainChangedFilter);

// RESTART MINING

Expand Down Expand Up @@ -792,15 +793,18 @@ void Client::noteChanged(h256Hash const& _filters)
cwatch << "!!!" << w.first << w.second.id.abridged();
w.second.changes += m_filters.at(w.second.id).changes;
}
else
{
cwatch << "!!!" << w.first << LogTag::Special << (w.second.id == PendingChangedFilter ? "pending" : w.second.id == ChainChangedFilter ? "chain" : "???");
w.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, 0));
}
else if (m_specialFilters.count(w.second.id))
for (h256 const& hash: m_specialFilters.at(w.second.id))
{
cwatch << "!!!" << w.first << LogTag::Special << (w.second.id == PendingChangedFilter ? "pending" : w.second.id == ChainChangedFilter ? "chain" : "???");
w.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, hash));
}
}
// clear the filters now.
for (auto& i: m_filters)
i.second.changes.clear();
for (auto& i: m_specialFilters)
i.second.clear();
}

void Client::doWork()
Expand Down
33 changes: 27 additions & 6 deletions libethereum/ClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ LocalisedLogEntries ClientBase::logs(unsigned _watchId) const
LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const
{
LocalisedLogEntries ret;
unsigned begin = min<unsigned>(bc().number() + 1, (unsigned)_f.latest());
unsigned end = min(bc().number(), min(begin, (unsigned)_f.earliest()));
unsigned begin = min(bc().number() + 1, (unsigned)numberFromHash(_f.latest()));
unsigned end = min(bc().number(), min(begin, (unsigned)numberFromHash(_f.earliest())));

// Handle pending transactions differently as they're not on the block chain.
if (begin > bc().number())
Expand All @@ -182,11 +182,10 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const
{
// Might have a transaction that contains a matching log.
TransactionReceipt const& tr = temp.receipt(i);
auto th = temp.pending()[i].sha3();
LogEntries le = _f.matches(tr);
if (le.size())
for (unsigned j = 0; j < le.size(); ++j)
ret.insert(ret.begin(), LocalisedLogEntry(le[j], begin, th));
ret.insert(ret.begin(), LocalisedLogEntry(le[j]));
}
begin = bc().number();
}
Expand All @@ -201,20 +200,22 @@ LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const
{
int total = 0;
auto h = bc().numberHash(n);
auto info = bc().info(h);
auto receipts = bc().receipts(h).receipts;
unsigned logIndex = 0;
for (size_t i = 0; i < receipts.size(); i++)
{
logIndex++;
TransactionReceipt receipt = receipts[i];
if (_f.matches(receipt.bloom()))
{
auto info = bc().info(h);
auto th = transaction(info.hash(), i).sha3();
LogEntries le = _f.matches(receipt);
if (le.size())
{
total += le.size();
for (unsigned j = 0; j < le.size(); ++j)
ret.insert(ret.begin(), LocalisedLogEntry(le[j], n, th));
ret.insert(ret.begin(), LocalisedLogEntry(le[j], info, th, i, logIndex));
}
}

Expand Down Expand Up @@ -313,6 +314,8 @@ LocalisedLogEntries ClientBase::checkWatch(unsigned _watchId)

BlockInfo ClientBase::blockInfo(h256 _hash) const
{
if (_hash == PendingBlockHash)
return preMine().info();
return BlockInfo(bc().block(_hash));
}

Expand Down Expand Up @@ -441,6 +444,24 @@ h256 ClientBase::hashFromNumber(BlockNumber _number) const

BlockNumber ClientBase::numberFromHash(h256 _blockHash) const
{
if (_blockHash == PendingBlockHash)
return bc().number() + 1;
else if (_blockHash == LatestBlockHash)
return bc().number();
else if (_blockHash == EarliestBlockHash)
return 0;
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;
}
5 changes: 4 additions & 1 deletion libethereum/ClientBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static const h256 PendingChangedFilter = u256(0);
static const h256 ChainChangedFilter = u256(1);

static const LogEntry SpecialLogEntry = LogEntry(Address(), h256s(), bytes());
static const LocalisedLogEntry InitialChange(SpecialLogEntry, 0);
static const LocalisedLogEntry InitialChange(SpecialLogEntry);

struct ClientWatch
{
Expand Down Expand Up @@ -117,6 +117,7 @@ class ClientBase: public Interface

virtual h256 hashFromNumber(BlockNumber _number) const override;
virtual BlockNumber numberFromHash(h256 _blockHash) const override;
virtual int compareBlockHashes(h256 _h1, h256 _h2) const override;
virtual BlockInfo blockInfo(h256 _hash) const override;
virtual BlockDetails blockDetails(h256 _hash) const override;
virtual Transaction transaction(h256 _transactionHash) const override;
Expand Down Expand Up @@ -175,6 +176,8 @@ class ClientBase: public Interface
// filters
mutable Mutex x_filtersWatches; ///< Our lock.
std::unordered_map<h256, InstalledFilter> m_filters; ///< The dictionary of filters that are active.
std::unordered_map<h256, h256s> m_specialFilters = std::unordered_map<h256, std::vector<h256>>{{PendingChangedFilter, {}}, {ChainChangedFilter, {}}};
///< The dictionary of special filters and their additional data
std::map<unsigned, ClientWatch> m_watches; ///< Each and every watch - these reference a filter.
};

Expand Down
1 change: 1 addition & 0 deletions libethereum/Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class Interface
virtual std::pair<h256, unsigned> transactionLocation(h256 const& _transactionHash) const = 0;
virtual h256 hashFromNumber(BlockNumber _number) const = 0;
virtual BlockNumber numberFromHash(h256 _blockHash) const = 0;
virtual int compareBlockHashes(h256 _h1, h256 _h2) const = 0;

virtual BlockInfo blockInfo(h256 _hash) const = 0;
virtual BlockDetails blockDetails(h256 _hash) const = 0;
Expand Down
27 changes: 0 additions & 27 deletions libethereum/LogFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,6 @@ h256 LogFilter::sha3() const
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
{
if (m_addresses.size())
Expand Down
15 changes: 7 additions & 8 deletions libethereum/LogFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,32 +45,31 @@ class State;
class LogFilter
{
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;
h256 sha3() const;

unsigned earliest() const { return m_earliest; }
unsigned latest() const { return m_latest; }
h256 earliest() const { return m_earliest; }
h256 latest() const { return m_latest; }

bool envelops(RelativeBlock _logBlockRelation, u256 _logBlockNumber) const;
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 withEarliest(int _e) { m_earliest = _e; return *this; }
LogFilter withLatest(int _e) { m_latest = _e; return *this; }
LogFilter withEarliest(h256 _e) { m_earliest = _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);

private:
AddressHash m_addresses;
std::array<h256Hash, 4> m_topics;
unsigned m_earliest = 0;
unsigned m_latest = LatestBlock;
h256 m_earliest = EarliestBlockHash;
h256 m_latest = PendingBlockHash;
};

}
Expand Down
26 changes: 22 additions & 4 deletions libevm/ExtVMFace.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,28 @@ using LogEntries = std::vector<LogEntry>;
struct LocalisedLogEntry: public LogEntry
{
LocalisedLogEntry() {}
LocalisedLogEntry(LogEntry const& _le, unsigned _number, h256 _transactionHash = h256()): LogEntry(_le), number(_number), transactionHash(_transactionHash) {}

unsigned number = 0;
h256 transactionHash;
explicit LocalisedLogEntry(LogEntry const& _le): LogEntry(_le) {};

explicit LocalisedLogEntry(
LogEntry const& _le,
h256 _special
): LogEntry(_le), special(_special) {};

explicit LocalisedLogEntry(
LogEntry const& _le,
BlockInfo const& _bi,
h256 _th,
unsigned _ti,
unsigned _li
): LogEntry(_le), blockHash(_bi.hash()), blockNumber((BlockNumber)_bi.number), transactionHash(_th), transactionIndex(_ti), logIndex(_li), mined(true) {};

h256 blockHash = h256();
BlockNumber blockNumber = 0;
h256 transactionHash = h256();
unsigned transactionIndex = 0;
unsigned logIndex = 0;
bool mined = false;
h256 special = h256();
};

using LocalisedLogEntries = std::vector<LocalisedLogEntry>;
Expand Down
Loading

0 comments on commit 413848c

Please sign in to comment.