Ejemplo n.º 1
0
LocalisedLogEntries ClientBase::logs(LogFilter const& _f) const
{
	LocalisedLogEntries ret;
	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())
	{
		State temp = postMine();
		for (unsigned i = 0; i < temp.pending().size(); ++i)
		{
			// Might have a transaction that contains a matching log.
			TransactionReceipt const& tr = temp.receipt(i);
			LogEntries le = _f.matches(tr);
			if (le.size())
				for (unsigned j = 0; j < le.size(); ++j)
					ret.insert(ret.begin(), LocalisedLogEntry(le[j]));
		}
		begin = bc().number();
	}
	
	set<unsigned> matchingBlocks;
	for (auto const& i: _f.bloomPossibilities())
		for (auto u: bc().withBlockBloom(i, end, begin))
			matchingBlocks.insert(u);

	unsigned falsePos = 0;
	for (auto n: matchingBlocks)
	{
		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 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], info, th, i, logIndex));
				}
			}
			
			if (!total)
				falsePos++;
		}
	}

	cdebug << matchingBlocks.size() << "searched from" << (end - begin) << "skipped; " << falsePos << "false +ves";
	return ret;
}
Ejemplo n.º 2
0
LogEntries LogFilter::matches(TransactionReceipt const& _m) const
{
	// there are no addresses or topics to filter
	if (isRangeFilter())
		return _m.log();

	LogEntries ret;
	if (matches(_m.bloom()))
		for (LogEntry const& e: _m.log())
		{
			if (!m_addresses.empty() && !m_addresses.count(e.address))
				goto continue2;
			for (unsigned i = 0; i < 4; ++i)
				if (!m_topics[i].empty() && (e.topics.size() < i || !m_topics[i].count(e.topics[i])))
					goto continue2;
			ret.push_back(e);
			continue2:;
		}
	return ret;
}