Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging topic lists when creating filters not possible in current api. Yields unexpected results. #975

Closed
dylanjw opened this issue Jul 30, 2018 · 2 comments

Comments

@dylanjw
Copy link
Contributor

dylanjw commented Jul 30, 2018

What was wrong?

The contract.events.myEvent.createFilter and contract.eventFilter both allow entering topics directly along with "argument filters" via filter param dict. The implementation is built on a false assumption about the topic list. The constructed topics are merged with the raw topics in a simple list addition:

    if topics is None:
        topic_set = construct_event_topic_set(event_abi, argument_filters)
    else:
        topic_set = [topics] + construct_event_topic_set(event_abi, argument_filters)

Merging two topic lists with additive results is impossible with a single filter. Merging two topic lists by using the available OR logic within single topic positions would yield all topic combinations.

Example:
Given the following "logs": AA BB AB
Topic list 1 ["A", "A"] would match AA
Topic list 2 ["B", "B"] would match BB
merged list [["A", "B"], ["A","B"]] would match AA BB AB

How can it be fixed?

Option 1. Remove option of entering raw topics along with argument filters that generate topics.
Option 2. Provide the functionality of merging topic lists, by extending the Filter object to manage multiple node filters.

something like:

FilterAggregator(Filter):
    def __init__(self, web3, filter_ids):
        self.web3 = web3
        self.filter_ids = filter_ids
    
    def get_new_entries(self):
        log_entries = mapcat(
            compose(self._filter_valid_entries, self.web3.eth.getFilterChanges),
            filter_ids)
        return self._format_log_entries(log_entries)

    def get_all_entries(self):
            log_entries = mapcat(
                compose(self._filter_valid_entries, self.web3.eth.getFilterLogs),
                self.filter_ids)
        return self._format_log_entries(log_entries)
@dylanjw
Copy link
Contributor Author

dylanjw commented Jul 30, 2018

There isnt a test that proves this, but Im 99% sure that this is broken. I'll write the broken test before starting on either option to fix.

@carver
Copy link
Collaborator

carver commented Jul 30, 2018

I think Option 1 is better. Clearly it's subtle enough that reasonable people can get confused by what merging is supposed to do. So let's just remove the opportunity for mistake. People can still manually merge topics themselves first, if they like.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants