def __init__(self, event_abi, formatter=None):
     self.event_abi = event_abi
     self.formatter = formatter
     self.event_topic = initialize_event_topics(self.event_abi)
     self.args = AttributeDict(
         _build_argument_filters_from_event_abi(event_abi))
     self._ordered_arg_names = tuple(arg['name']
                                     for arg in event_abi['inputs'])
示例#2
0
def test_attributedict_dict_in_list_in_dict():
    data = {'instructions': [
        0,
        1,
        'neither shalt thou count, excepting that thou then proceedeth to three',
        {'if_naughty': 'snuff it'},
        'shalt thou not count',
        'right out',
    ]}
    attrdict = AttributeDict.recursive(data)
    assert attrdict.instructions[3].if_naughty == 'snuff it'
示例#3
0
    def middleware(method, params):
        response = make_request(method, params)

        if 'result' in response:
            result = response['result']
            if is_dict(result) and not isinstance(result, AttributeDict):
                return assoc(response, 'result',
                             AttributeDict.recursive(result))
            else:
                return response
        else:
            return response
class EventFilterBuilder:
    formatter = None
    _fromBlock = None
    _toBlock = None
    _address = None
    _immutable = False

    def __init__(self, event_abi, formatter=None):
        self.event_abi = event_abi
        self.formatter = formatter
        self.event_topic = initialize_event_topics(self.event_abi)
        self.args = AttributeDict(
            _build_argument_filters_from_event_abi(event_abi))
        self._ordered_arg_names = tuple(arg['name']
                                        for arg in event_abi['inputs'])

    @property
    def fromBlock(self):
        return self._fromBlock

    @fromBlock.setter
    def fromBlock(self, value):
        if self._fromBlock is None and not self._immutable:
            self._fromBlock = value
        else:
            raise ValueError(
                "fromBlock is already set to {0}. "
                "Resetting filter parameters is not permitted".format(
                    self._fromBlock))

    @property
    def toBlock(self):
        return self._toBlock

    @toBlock.setter
    def toBlock(self, value):
        if self._toBlock is None and not self._immutable:
            self._toBlock = value
        else:
            raise ValueError(
                "toBlock is already set to {0}. "
                "Resetting filter parameters is not permitted".format(
                    self._toBlock))

    @property
    def address(self):
        return self._address

    @address.setter
    def address(self, value):
        if self._address is None and not self._immutable:
            self._address = value
        else:
            raise ValueError(
                "address is already set to {0}. "
                "Resetting filter parameters is not permitted".format(
                    self.address))

    @property
    def ordered_args(self):
        return tuple(map(self.args.__getitem__, self._ordered_arg_names))

    @property
    @to_tuple
    def indexed_args(self):
        return tuple(filter(is_indexed, self.ordered_args))

    @property
    @to_tuple
    def data_args(self):
        return tuple(filter(is_not_indexed, self.ordered_args))

    @property
    def topics(self):
        arg_topics = tuple(arg.match_values for arg in self.indexed_args)
        return normalize_topic_list(cons(to_hex(self.event_topic), arg_topics))

    @property
    def data_argument_values(self):
        if self.data_args is not None:
            return tuple(arg.match_values for arg in self.data_args)
        else:
            return (None, )

    @property
    def filter_params(self):
        params = {
            "topics": self.topics,
            "fromBlock": self.fromBlock,
            "toBlock": self.toBlock,
            "address": self.address
        }
        return valfilter(lambda x: x is not None, params)

    def deploy(self, w3):
        if not isinstance(w3, web3.Web3):
            raise ValueError("Invalid web3 argument: got: {0}".format(
                repr(w3)))

        for arg in self.args.values():
            arg._immutable = True
        self._immutable = True

        log_filter = w3.eth.filter(self.filter_params)
        log_filter.filter_params = self.filter_params
        log_filter.set_data_filters(self.data_argument_values)
        log_filter.builder = self
        if self.formatter is not None:
            log_filter.log_entry_formatter = self.formatter
        return log_filter
def get_event_data(event_abi, log_entry):
    """
    Given an event ABI and a log entry for that event, return the decoded
    event data
    """
    if event_abi['anonymous']:
        log_topics = log_entry['topics']
    elif not log_entry['topics']:
        raise MismatchedABI(
            "Expected non-anonymous event to have 1 or more topics")
    elif event_abi_to_log_topic(event_abi) != log_entry['topics'][0]:
        raise MismatchedABI(
            "The event signature did not match the provided ABI")
    else:
        log_topics = log_entry['topics'][1:]

    log_topics_abi = get_indexed_event_inputs(event_abi)
    log_topic_normalized_inputs = normalize_event_input_types(log_topics_abi)
    log_topic_types = get_event_abi_types_for_decoding(
        log_topic_normalized_inputs)
    log_topic_names = get_abi_input_names({'inputs': log_topics_abi})

    if len(log_topics) != len(log_topic_types):
        raise ValueError("Expected {0} log topics.  Got {1}".format(
            len(log_topic_types),
            len(log_topics),
        ))

    log_data = hexstr_if_str(to_bytes, log_entry['data'])
    log_data_abi = exclude_indexed_event_inputs(event_abi)
    log_data_normalized_inputs = normalize_event_input_types(log_data_abi)
    log_data_types = get_event_abi_types_for_decoding(
        log_data_normalized_inputs)
    log_data_names = get_abi_input_names({'inputs': log_data_abi})

    # sanity check that there are not name intersections between the topic
    # names and the data argument names.
    duplicate_names = set(log_topic_names).intersection(log_data_names)
    if duplicate_names:
        raise ValueError(
            "Invalid Event ABI:  The following argument names are duplicated "
            "between event inputs: '{0}'".format(', '.join(duplicate_names)))

    decoded_log_data = decode_abi(log_data_types, log_data)
    normalized_log_data = map_abi_data(BASE_RETURN_NORMALIZERS, log_data_types,
                                       decoded_log_data)

    decoded_topic_data = [
        decode_single(topic_type, topic_data)
        for topic_type, topic_data in zip(log_topic_types, log_topics)
    ]
    normalized_topic_data = map_abi_data(BASE_RETURN_NORMALIZERS,
                                         log_topic_types, decoded_topic_data)

    event_args = dict(
        itertools.chain(
            zip(log_topic_names, normalized_topic_data),
            zip(log_data_names, normalized_log_data),
        ))

    event_data = {
        'args': event_args,
        'event': event_abi['name'],
        'logIndex': log_entry['logIndex'],
        'transactionIndex': log_entry['transactionIndex'],
        'transactionHash': log_entry['transactionHash'],
        'address': log_entry['address'],
        'blockHash': log_entry['blockHash'],
        'blockNumber': log_entry['blockNumber'],
    }

    return AttributeDict.recursive(event_data)
示例#6
0
def stub_block(timestamp):
    return AttributeDict({
        'timestamp': timestamp,
        'number': 123,
    })
示例#7
0
        ('0x0', '0x0'),
        ('0x1', '0x1'),
        ('0x0001', '0x0001'),
        ('0x10', '0x10'),
        ('0xF', '0xf'),
        ('F', '0xf'),
    ),
)
def test_to_hex_cleanup_only(val, expected):
    assert Web3.toHex(hexstr=val) == expected


@pytest.mark.parametrize(
    'val, expected',
    (
        (AttributeDict({'one': HexBytes('0x1')}), '{"one": "0x01"}'),
        (AttributeDict({'two': HexBytes(2)}), '{"two": "0x02"}'),
        (AttributeDict({'three': AttributeDict({'four': 4})
                        }), '{"three": {"four": 4}}'),
        ({
            'three': 3
        }, '{"three": 3}'),
    ),
)
def test_to_json(val, expected):
    assert Web3.toJSON(val) == expected


@pytest.mark.parametrize(
    'tx, expected',
    (
示例#8
0
def test_attributedict_recursive_dict():
    w = AttributeDict.recursive({'x': {'y': {'z': 8}}})
    assert w.x.y.z == 8
示例#9
0
def test_attributedict_sequence_with_dict(sequence):
    data = sequence(['a', {'found': True}, 'c'])
    dict_in_sequence = AttributeDict.recursive(data)
    assert dict_in_sequence[1].found is True
示例#10
0
def test_attributedict_equality(dict1, dict2):
    assert AttributeDict(dict1) == dict2
    assert AttributeDict(dict1) == AttributeDict(dict2)
    assert dict1 == AttributeDict(dict2)
示例#11
0
def test_attributedict_inequality(dict1, dict2):
    assert AttributeDict(dict1) != dict2
    assert AttributeDict(dict1) != AttributeDict(dict2)
    assert dict1 != AttributeDict(dict2)
示例#12
0
def test_attributedict_delitem_invalid():
    container = AttributeDict({'a': 1})
    with pytest.raises(TypeError):
        del container['a']
    assert container['a'] == 1
示例#13
0
def test_attributedict_setattr_invalid():
    container = AttributeDict({'a': 1})
    with pytest.raises(TypeError):
        container.a = 0
    assert container.a == 1
示例#14
0
def test_attributedict_repr():
    dict1 = AttributeDict({'a': 1})
    dict2 = eval(repr(dict1))
    assert dict1 == dict2
示例#15
0
def test_attributedict_access():
    container = AttributeDict({'a': 1})
    assert container.a == 1
示例#16
0
def test_attributedict_set_in_recursive_dict():
    data = {'mydict': {'myset': {'found'}}}
    attrdict = AttributeDict.recursive(data)
    assert 'found' in attrdict.mydict.myset