Esempio n. 1
0
def test_uint_math():
    assert uint8(0) + uint8(uint32(16)) == uint8(
        16)  # allow explicit casting to make invalid addition valid

    expect_op_error(lambda: uint8(0) - uint8(1), "no underflows allowed")
    expect_op_error(lambda: uint8(1) + uint8(255), "no overflows allowed")
    expect_op_error(lambda: uint8(0) + 256, "no overflows allowed")
    expect_op_error(lambda: uint8(42) + uint32(123), "no mixed types")
    expect_op_error(lambda: uint32(42) + uint8(123), "no mixed types")

    assert type(uint32(1234) + 56) == uint32
Esempio n. 2
0
 def deserialize(cls: Type[M], stream: BinaryIO, scope: int) -> M:
     elem_cls = cls.element_cls()
     if elem_cls.is_fixed_byte_length():
         elem_byte_length = elem_cls.type_byte_length()
         if scope % elem_byte_length != 0:
             raise Exception(
                 f"scope {scope} does not match element byte length {elem_byte_length} multiple"
             )
         count = scope // elem_byte_length
         if not cls.is_valid_count(count):
             raise Exception(f"count {count} is invalid")
         return cls(
             elem_cls.deserialize(stream, elem_byte_length)
             for _ in range(count))  # type: ignore
     else:
         if scope == 0:
             if not cls.is_valid_count(0):
                 raise Exception("scope cannot be 0, count must not be 0")
             return cls()
         first_offset = decode_offset(stream)
         if first_offset > scope:
             raise Exception(
                 f"first offset is too big: {first_offset}, scope: {scope}")
         if first_offset % OFFSET_BYTE_LENGTH != 0:
             raise Exception(
                 f"first offset {first_offset} is not a multiple of offset length {OFFSET_BYTE_LENGTH}"
             )
         count = first_offset // OFFSET_BYTE_LENGTH
         if not cls.is_valid_count(count):
             raise Exception(f"count {count} is invalid")
         # count - 1: we already have the first offset
         offsets = [first_offset
                    ] + [decode_offset(stream)
                         for _ in range(count - 1)] + [uint32(scope)]
         elem_min, elem_max = elem_cls.min_byte_length(
         ), elem_cls.max_byte_length()
         elems = []
         for i in range(count):
             start, end = offsets[i], offsets[i + 1]
             if end < start:
                 raise Exception(
                     f"offsets[{i}] value {start} is invalid, next offset is {end}"
                 )
             elem_size = end - start
             if not (elem_min <= elem_size <= elem_max):
                 raise Exception(
                     f"offset[{i}] value {start} is invalid, next offset is {end},"
                     f" implied size is {elem_size}, size bounds: [{elem_min}, {elem_max}]"
                 )
             elems.append(elem_cls.deserialize(stream, elem_size))
         return cls(*elems)  # type: ignore
Esempio n. 3
0
def encode_offset(stream: BinaryIO, offset: int):
    return uint32(offset).serialize(stream)
Esempio n. 4
0
def test_list():
    typ = List[uint64, 128]
    assert issubclass(typ, List)
    assert issubclass(typ, View)
    assert isinstance(typ, TypeDef)

    assert not typ.is_fixed_byte_length()

    assert len(typ()) == 0  # empty
    assert len(typ(uint64(0))) == 1  # single arg
    assert len(typ(uint64(i) for i in range(10))) == 10  # generator
    assert len(typ(uint64(0), uint64(1), uint64(2))) == 3  # args
    assert isinstance(typ(1, 2, 3, 4, 5)[4], uint64)  # coercion
    assert isinstance(typ(i for i in range(10))[9],
                      uint64)  # coercion in generator

    v = typ(uint64(2), uint64(1))
    v[0] = uint64(123)
    assert v[0] == 123
    assert isinstance(v[0], uint64)

    assert isinstance(v, List)
    assert isinstance(v, View)

    assert len(typ([i for i in range(10)])) == 10  # cast py list to SSZ list

    foo = List[uint32, 128](0 for i in range(128))
    foo[0] = 123
    foo[1] = 654
    foo[127] = 222
    assert sum(foo) == 999
    try:
        foo[3] = 2**32  # out of bounds
    except ValueError:
        pass

    for i in range(128):
        foo.pop()
        assert len(foo) == 128 - 1 - i
    for i in range(128):
        foo.append(uint32(i))
        assert len(foo) == i + 1
        assert foo[i] == i

    try:
        foo[3] = uint64(2**32 - 1)  # within bounds, wrong type
        assert False
    except ValueError:
        pass

    try:
        foo[128] = 100
        assert False
    except IndexError:
        pass

    try:
        foo[-1] = 100  # valid in normal python lists
        assert False
    except IndexError:
        pass

    try:
        foo[128] = 100  # out of bounds
        assert False
    except IndexError:
        pass
Esempio n. 5
0
def test_container():
    class Foo(Container):
        a: uint8
        b: uint32

    empty = Foo()
    assert empty.a == uint8(0)
    assert empty.b == uint32(0)

    assert issubclass(Foo, Container)
    assert issubclass(Foo, View)

    assert Foo.is_fixed_byte_length()
    x = Foo(a=uint8(123), b=uint32(45))
    assert x.a == 123
    assert x.b == 45
    assert isinstance(x.a, uint8)
    assert isinstance(x.b, uint32)
    assert x.__class__.is_fixed_byte_length()

    class Bar(Container):
        a: uint8
        b: List[uint8, 1024]

    assert not Bar.is_fixed_byte_length()

    y = Bar(a=123, b=List[uint8, 1024](uint8(1), uint8(2)))
    assert y.a == 123
    assert isinstance(y.a, uint8)
    assert len(y.b) == 2
    assert isinstance(y.a, uint8)
    assert not y.__class__.is_fixed_byte_length()
    assert y.b[0] == 1
    v: List = y.b
    assert v.__class__.element_cls() == uint8
    assert v.__class__.limit() == 1024

    field_values = list(y)
    assert field_values == [y.a, y.b]

    f_a, f_b = y
    assert f_a == y.a
    assert f_b == y.b

    y.a = 42
    try:
        y.a = 256  # out of bounds
        assert False
    except ValueError:
        pass

    try:
        y.a = uint16(255)  # within bounds, wrong type
        assert False
    except ValueError:
        pass

    try:
        y.not_here = 5
        assert False
    except AttributeError:
        pass

    try:
        Foo(wrong_field_name=100)
        assert False
    except AttributeError:
        pass
Esempio n. 6
0
  "ff" * 64 + "01", h(h("ff" * 32, "ff" * 32),
                      h(chunk("01"),
                        chunk(""))), "0x" + ("ff" * 64) + "01"),
 ("odd bitlist", Bitlist[513], Bitlist[513](1 for i in range(513)),
  "ff" * 64 + "03",
  h(h(h("ff" * 32, "ff" * 32), h(chunk("01"), chunk(""))),
    chunk("0102")), "0x" + ("ff" * 64) + "03"),
 ("uint8 00", uint8, uint8(0x00), "00", chunk("00"), 0),
 ("uint8 01", uint8, uint8(0x01), "01", chunk("01"), 1),
 ("uint8 ab", uint8, uint8(0xab), "ab", chunk("ab"), 0xab),
 ("byte 00", byte, byte(0x00), "00", chunk("00"), 0),
 ("byte 01", byte, byte(0x01), "01", chunk("01"), 1),
 ("byte ab", byte, byte(0xab), "ab", chunk("ab"), 0xab),
 ("uint16 0000", uint16, uint16(0x0000), "0000", chunk("0000"), 0),
 ("uint16 abcd", uint16, uint16(0xabcd), "cdab", chunk("cdab"), 0xabcd),
 ("uint32 00000000", uint32, uint32(0x00000000), "00000000",
  chunk("00000000"), 0),
 ("uint32 01234567", uint32, uint32(0x01234567), "67452301",
  chunk("67452301"), 0x01234567),
 ("small (4567, 0123)", SmallTestStruct, SmallTestStruct(A=0x4567,
                                                         B=0x0123),
  "67452301", h(chunk("6745"), chunk("2301")), {
      'A': 0x4567,
      'B': 0x0123
  }),
 ("small [4567, 0123]::2", Vector[uint16,
                                  2], Vector[uint16,
                                             2](uint16(0x4567),
                                                uint16(0x0123)), "67452301",
  chunk("67452301"), (0x4567, 0x0123)),
 ("uint32 01234567", uint32, uint32(0x01234567), "67452301",
Esempio n. 7
0
def encode_offset(offset: int) -> bytes:
    return uint32(offset).encode_bytes()