Esempio n. 1
0
def infer_sedes(obj):
    """Try to find a sedes objects suitable for a given Python object.

    The sedes objects considered are `obj`'s class, `big_endian_int` and
    `binary`. If `obj` is a sequence, a :class:`rlp.sedes.List` will be
    constructed recursively.

    :param obj: the python object for which to find a sedes object
    :raises: :exc:`TypeError` if no appropriate sedes could be found
    """
    if is_sedes(obj.__class__):
        return obj.__class__
    elif not isinstance(obj, bool) and isinstance(obj, int) and obj >= 0:
        return big_endian_int
    elif BinaryClass.is_valid_type(obj):
        return binary
    elif not isinstance(obj, str) and isinstance(obj,
                                                 collections.abc.Sequence):
        return List(map(infer_sedes, obj))
    elif isinstance(obj, bool):
        return boolean
    elif isinstance(obj, str):
        return text
    msg = 'Did not find sedes handling type {}'.format(type(obj).__name__)
    raise TypeError(msg)
Esempio n. 2
0
class Log(rlp.Serializable):

    # TODO: original version used zpad (here replaced by int32.serialize); had
    # comment "why zpad"?
    fields = [
        ("address", Binary.fixed_length(20, allow_empty=True)),
        ("topics", CountableList(BigEndianInt(32))),
        ("data", binary),
    ]

    def __init__(self, address, topics, data):
        if len(address) == 40:
            address = decode_hex(address)
        assert len(address) == 20
        super(Log, self).__init__(address, topics, data)

    def bloomables(self):
        return [self.address] + [BigEndianInt(32).serialize(x) for x in self.topics]

    def to_dict(self):
        return {
            "bloom": encode_hex(bloom.b64(bloom.bloom_from_list(self.bloomables()))),
            "address": encode_hex(self.address),
            "data": b"0x" + encode_hex(self.data),
            "topics": [encode_hex(utils.int32.serialize(t)) for t in self.topics],
        }

    def __repr__(self):
        return "<Log(address=%r, topics=%r, data=%r)>" % (
            encode_hex(self.address),
            self.topics,
            self.data,
        )
Esempio n. 3
0
class Receipt(rlp.Serializable):

    fields = [
        ('state_root', binary),
        ('gas_used', big_endian_int),   # TODO: this is actually the cumulative gas used. fix it.
        ('bloom', int256),
        ('logs', CountableList(Log)),
        ('contract_address', Binary.fixed_length(20, allow_empty=True)),
        ('contract_full_shard_id', BigEndianInt(4)),
    ]

    def __init__(self, state_root, gas_used, logs, contract_address, contract_full_shard_id, bloom=None):
        # does not call super.__init__ as bloom should not be an attribute but
        # a property
        self.state_root = state_root
        self.gas_used = gas_used
        self.logs = logs
        if bloom is not None and bloom != self.bloom:
            raise ValueError("Invalid bloom filter")
        self.contract_address = contract_address
        self.contract_full_shard_id = contract_full_shard_id
        self._cached_rlp = None
        self._mutable = True

    @property
    def bloom(self):
        bloomables = [x.bloomables() for x in self.logs]
        return bloom.bloom_from_list(utils.flatten(bloomables))
Esempio n. 4
0
class Receipt(rlp.Serializable):
    fields = [
        ("state_root", binary),
        (
            "gas_used",
            big_endian_int,
        ),  # TODO: this is actually the cumulative gas used. fix it.
        ("bloom", int256),
        ("logs", CountableList(Log)),
        ("contract_address", Binary.fixed_length(20, allow_empty=True)),
        ("contract_full_shard_key", BigEndianInt(4)),
    ]

    @property
    def bloom(self):
        bloomables = [x.bloomables() for x in self.logs]
        return bloom.bloom_from_list(utils.flatten(bloomables))