Skip to content
This repository has been archived by the owner on Aug 8, 2018. It is now read-only.

Commit

Permalink
Merge pull request #168 from ethereum/logfilters_or_improved
Browse files Browse the repository at this point in the history
Logfilters or improved
  • Loading branch information
konradkonrad authored Aug 22, 2016
2 parents 60a56d2 + 528627d commit 8d27ab2
Show file tree
Hide file tree
Showing 3 changed files with 409 additions and 69 deletions.
50 changes: 43 additions & 7 deletions pyethapp/jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,12 @@ def filter_decoder(filter_dict, chain):
if 'topics' in filter_dict:
topics = []
for topic in filter_dict['topics']:
if topic is not None:
if type(topic) == list:
or_topics = []
for or_topic in topic:
or_topics.append(big_endian_to_int(data_decoder(or_topic)))
topics.append(or_topics)
elif topic is not None:
log.debug('with topic', topic=topic)
log.debug('decoded', topic=data_decoder(topic))
log.debug('int', topic=big_endian_to_int(data_decoder(topic)))
Expand Down Expand Up @@ -1295,7 +1300,11 @@ def __init__(self, chain, first_block, last_block, addresses=None, topics=None):
self.topics = topics
if self.topics:
for topic in self.topics:
assert topic is None or is_numeric(topic)
assert topic is None or is_numeric(topic) \
or type(topic) == list
if type(topic) == list:
for or_topic in topic:
assert or_topic is None or is_numeric(or_topic)

self.last_head = self.chain.head
self.last_block_checked = None
Expand Down Expand Up @@ -1352,6 +1361,7 @@ def check(self):
# go through all receipts of all blocks
# logger.debug('blocks to check', blocks=blocks_to_check)
new_logs = {}

for i, block in enumerate(blocks_to_check):
if not isinstance(block, (ethereum.blocks.Block, ethereum.blocks.CachedBlock)):
_bloom = self.chain.get_bloom(block)
Expand All @@ -1365,9 +1375,30 @@ def check(self):
if not pass_address_check:
continue
# Check that the bloom for this block contains all of the desired topics
_topic_bloom = bloom.bloom_from_list(map(int32.serialize, self.topics or []))
if bloom.bloom_combine(_bloom, _topic_bloom) != _bloom:
continue
or_topics = list()
and_topics = list()
for topic in self.topics or []:
if type(topic) == list:
or_topics += topic
else:
and_topics.append(topic)
if or_topics:
# In case of the frequent usage of multiple 'or' statements in the filter
# the following logic should be optimized so that the fewer amount of blocks gets checked.
# It is currently optimal for filters with a single 'or' statement.
_topic_and_bloom = bloom.bloom_from_list(map(int32.serialize, and_topics or []))
bloom_passed = False
for or_t in or_topics:
or_bl = bloom.bloom_from_list(map(int32.serialize, [or_t]))
if bloom.bloom_combine(_bloom, _topic_and_bloom, or_bl) == _bloom:
bloom_passed = True
break
if not bloom_passed:
continue
else:
_topic_bloom = bloom.bloom_from_list(map(int32.serialize, self.topics or []))
if bloom.bloom_combine(_bloom, _topic_bloom) != _bloom:
continue
block = self.chain.get(block)
print 'bloom filter passed'
logger.debug('-')
Expand All @@ -1384,8 +1415,13 @@ def check(self):
topic_match = False
for filter_topic, log_topic in zip(self.topics, log.topics):
if filter_topic is not None and filter_topic != log_topic:
logger.debug('topic mismatch', want=filter_topic, have=log_topic)
topic_match = False
if type(filter_topic) == list:
if log_topic not in filter_topic:
logger.debug('topic mismatch', want=filter_topic, have=log_topic)
topic_match = False
else:
logger.debug('topic mismatch', want=filter_topic, have=log_topic)
topic_match = False
if not topic_match:
continue
# check for address
Expand Down
9 changes: 6 additions & 3 deletions pyethapp/rpc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,13 @@ class JSONRPCClient(object):
protocol = JSONRPCProtocol()

def __init__(self, host='127.0.0.1', port=4000, print_communication=True,
privkey=None, sender=None, use_ssl=False):
privkey=None, sender=None, use_ssl=False, transport=None):
"specify privkey for local signing"
self.transport = HttpPostClientTransport('{}://{}:{}'.format(
'https' if use_ssl else 'http', host, port))
if transport is None:
self.transport = HttpPostClientTransport('{}://{}:{}'.format(
'https' if use_ssl else 'http', host, port))
else:
self.transport = transport
self.print_communication = print_communication
self.privkey = privkey
self._sender = sender
Expand Down
Loading

0 comments on commit 8d27ab2

Please sign in to comment.