示例#1
0
def test_TupleElement_store_into():
    tests: List[List[abi.TypeSpec]] = [
        [],
        [abi.Uint64TypeSpec()],
        [
            abi.TupleTypeSpec(abi.Uint64TypeSpec(), abi.Uint64TypeSpec()),
            abi.Uint64TypeSpec(),
        ],
        [abi.BoolTypeSpec()] * 8,
    ]

    for i, test in enumerate(tests):
        tupleValue = abi.Tuple(abi.TupleTypeSpec(*test))
        for j in range(len(test)):
            element = TupleElement(tupleValue, j)
            output = test[j].new_instance()

            expr = element.store_into(output)
            assert expr.type_of() == pt.TealType.none
            assert not expr.has_return()

            expectedExpr = _index_tuple(test, tupleValue.encode(), j, output)
            expected, _ = expectedExpr.__teal__(options)
            expected.addIncoming()
            expected = pt.TealBlock.NormalizeBlocks(expected)

            actual, _ = expr.__teal__(options)
            actual.addIncoming()
            actual = pt.TealBlock.NormalizeBlocks(actual)

            with pt.TealComponent.Context.ignoreExprEquality():
                assert actual == expected, "Test at index {} failed".format(i)
示例#2
0
def test_Tuple_length():
    tests: List[List[abi.TypeSpec]] = [
        [],
        [abi.Uint64TypeSpec()],
        [
            abi.TupleTypeSpec(abi.Uint64TypeSpec(), abi.Uint64TypeSpec()),
            abi.Uint64TypeSpec(),
        ],
        [abi.BoolTypeSpec()] * 8,
    ]

    for i, test in enumerate(tests):
        tupleValue = abi.Tuple(abi.TupleTypeSpec(*test))
        expr = tupleValue.length()
        assert expr.type_of() == pt.TealType.uint64
        assert not expr.has_return()

        expectedLength = len(test)
        expected = pt.TealSimpleBlock([pt.TealOp(None, pt.Op.int, expectedLength)])

        actual, _ = expr.__teal__(options)
        actual.addIncoming()
        actual = pt.TealBlock.NormalizeBlocks(actual)

        with pt.TealComponent.Context.ignoreExprEquality():
            assert actual == expected, "Test at index {} failed".format(i)
示例#3
0
def test_Tuple_set_Computed():
    tupleValue = abi.Tuple(
        abi.TupleTypeSpec(
            abi.Uint8TypeSpec(), abi.Uint16TypeSpec(), abi.Uint32TypeSpec()
        )
    )
    computed = ContainerType(
        tupleValue.type_spec(), pt.Bytes("internal representation")
    )
    expr = tupleValue.set(computed)
    assert expr.type_of() == pt.TealType.none
    assert not expr.has_return()

    expected = pt.TealSimpleBlock(
        [
            pt.TealOp(None, pt.Op.byte, '"internal representation"'),
            pt.TealOp(None, pt.Op.store, tupleValue.stored_value.slot),
        ]
    )
    actual, _ = expr.__teal__(options)
    actual.addIncoming()
    actual = pt.TealBlock.NormalizeBlocks(actual)

    with pt.TealComponent.Context.ignoreExprEquality():
        assert actual == expected

    with pytest.raises(pt.TealInputError):
        tupleValue.set(computed, computed)

    with pytest.raises(pt.TealInputError):
        tupleValue.set(
            ContainerType(abi.TupleTypeSpec(abi.ByteTypeSpec()), pt.Bytes(b"a"))
        )
示例#4
0
def test_Tuple_encode():
    tupleValue = abi.Tuple(abi.TupleTypeSpec(abi.Uint64TypeSpec()))
    expr = tupleValue.encode()
    assert expr.type_of() == pt.TealType.bytes
    assert not expr.has_return()

    expected = pt.TealSimpleBlock(
        [pt.TealOp(None, pt.Op.load, tupleValue.stored_value.slot)]
    )

    actual, _ = expr.__teal__(options)
    actual.addIncoming()
    actual = pt.TealBlock.NormalizeBlocks(actual)

    with pt.TealComponent.Context.ignoreExprEquality():
        assert actual == expected
示例#5
0
def test_Tuple_set():
    tupleValue = abi.Tuple(
        abi.TupleTypeSpec(
            abi.Uint8TypeSpec(), abi.Uint16TypeSpec(), abi.Uint32TypeSpec()
        )
    )
    uint8 = abi.Uint8()
    uint16 = abi.Uint16()
    uint32 = abi.Uint32()

    with pytest.raises(pt.TealInputError):
        tupleValue.set()

    with pytest.raises(pt.TealInputError):
        tupleValue.set(uint8, uint16)

    with pytest.raises(pt.TealInputError):
        tupleValue.set(uint8, uint16, uint32, uint32)

    with pytest.raises(pt.TealInputError):
        tupleValue.set(uint8, uint32, uint16)

    with pytest.raises(pt.TealInputError):
        tupleValue.set(uint8, uint16, uint16)

    expr = tupleValue.set(uint8, uint16, uint32)
    assert expr.type_of() == pt.TealType.none
    assert not expr.has_return()

    expectedExpr = tupleValue.stored_value.store(_encode_tuple([uint8, uint16, uint32]))
    expected, _ = expectedExpr.__teal__(options)
    expected.addIncoming()
    expected = pt.TealBlock.NormalizeBlocks(expected)

    actual, _ = expr.__teal__(options)
    actual.addIncoming()
    actual = pt.TealBlock.NormalizeBlocks(actual)

    with pt.TealComponent.Context.ignoreExprEquality():
        assert actual == expected
示例#6
0
def test_Tuple_decode():
    encoded = pt.Bytes("encoded")
    tupleValue = abi.Tuple(abi.TupleTypeSpec(abi.Uint64TypeSpec()))
    for start_index in (None, pt.Int(1)):
        for end_index in (None, pt.Int(2)):
            for length in (None, pt.Int(3)):
                if end_index is not None and length is not None:
                    with pytest.raises(pt.TealInputError):
                        tupleValue.decode(
                            encoded,
                            start_index=start_index,
                            end_index=end_index,
                            length=length,
                        )
                    continue

                expr = tupleValue.decode(
                    encoded, start_index=start_index, end_index=end_index, length=length
                )
                assert expr.type_of() == pt.TealType.none
                assert not expr.has_return()

                expectedExpr = tupleValue.stored_value.store(
                    substring_for_decoding(
                        encoded,
                        start_index=start_index,
                        end_index=end_index,
                        length=length,
                    )
                )
                expected, _ = expectedExpr.__teal__(options)
                expected.addIncoming()
                expected = pt.TealBlock.NormalizeBlocks(expected)

                actual, _ = expr.__teal__(options)
                actual.addIncoming()
                actual = pt.TealBlock.NormalizeBlocks(actual)

                with pt.TealComponent.Context.ignoreExprEquality():
                    assert actual == expected
示例#7
0
def test_Tuple_getitem():
    tests: List[List[abi.TypeSpec]] = [
        [],
        [abi.Uint64TypeSpec()],
        [
            abi.TupleTypeSpec(abi.Uint64TypeSpec(), abi.Uint64TypeSpec()),
            abi.Uint64TypeSpec(),
        ],
        [abi.BoolTypeSpec()] * 8,
    ]

    for i, test in enumerate(tests):
        tupleValue = abi.Tuple(abi.TupleTypeSpec(*test))
        for j in range(len(test)):
            element = tupleValue[j]
            assert type(element) is TupleElement, "Test at index {} failed".format(i)
            assert element.tuple is tupleValue, "Test at index {} failed".format(i)
            assert element.index == j, "Test at index {} failed".format(i)

        with pytest.raises(pt.TealInputError):
            tupleValue[-1]

        with pytest.raises(pt.TealInputError):
            tupleValue[len(test)]
示例#8
0
def test_ArrayElement_store_into():
    for elementType in STATIC_TYPES + DYNAMIC_TYPES:
        staticArrayType = abi.StaticArrayTypeSpec(elementType, 100)
        staticArray = staticArrayType.new_instance()
        index = pt.Int(9)

        element = abi.ArrayElement(staticArray, index)
        output = elementType.new_instance()
        expr = element.store_into(output)

        encoded = staticArray.encode()
        stride = pt.Int(staticArray.type_spec()._stride())
        expectedLength = staticArray.length()
        if elementType == abi.BoolTypeSpec():
            expectedExpr = cast(abi.Bool, output).decode_bit(encoded, index)
        elif not elementType.is_dynamic():
            expectedExpr = output.decode(encoded,
                                         start_index=stride * index,
                                         length=stride)
        else:
            expectedExpr = output.decode(
                encoded,
                start_index=pt.ExtractUint16(encoded, stride * index),
                end_index=pt.If(index + pt.Int(1) == expectedLength).Then(
                    pt.Len(encoded)).Else(
                        pt.ExtractUint16(encoded, stride * index + pt.Int(2))),
            )

        expected, _ = expectedExpr.__teal__(options)
        expected.addIncoming()
        expected = pt.TealBlock.NormalizeBlocks(expected)

        actual, _ = expr.__teal__(options)
        actual.addIncoming()
        actual = pt.TealBlock.NormalizeBlocks(actual)

        with pt.TealComponent.Context.ignoreExprEquality():
            assert actual == expected

        with pytest.raises(pt.TealInputError):
            element.store_into(abi.Tuple(abi.TupleTypeSpec(elementType)))

    for elementType in STATIC_TYPES + DYNAMIC_TYPES:
        dynamicArrayType = abi.DynamicArrayTypeSpec(elementType)
        dynamicArray = dynamicArrayType.new_instance()
        index = pt.Int(9)

        element = abi.ArrayElement(dynamicArray, index)
        output = elementType.new_instance()
        expr = element.store_into(output)

        encoded = dynamicArray.encode()
        stride = pt.Int(dynamicArray.type_spec()._stride())
        expectedLength = dynamicArray.length()
        if elementType == abi.BoolTypeSpec():
            expectedExpr = cast(abi.Bool,
                                output).decode_bit(encoded, index + pt.Int(16))
        elif not elementType.is_dynamic():
            expectedExpr = output.decode(encoded,
                                         start_index=stride * index +
                                         pt.Int(2),
                                         length=stride)
        else:
            expectedExpr = output.decode(
                encoded,
                start_index=pt.ExtractUint16(
                    encoded, stride * index + pt.Int(2)) + pt.Int(2),
                end_index=pt.If(index + pt.Int(1) == expectedLength).Then(
                    pt.Len(encoded)).Else(
                        pt.ExtractUint16(
                            encoded, stride * index + pt.Int(2) + pt.Int(2)) +
                        pt.Int(2)),
            )

        expected, _ = expectedExpr.__teal__(options)
        expected.addIncoming()
        expected = pt.TealBlock.NormalizeBlocks(expected)

        actual, _ = expr.__teal__(options)
        actual.addIncoming()
        actual = pt.TealBlock.NormalizeBlocks(actual)

        with pt.TealComponent.Context.ignoreExprEquality():
            with pt.TealComponent.Context.ignoreScratchSlotEquality():
                assert actual == expected

        assert pt.TealBlock.MatchScratchSlotReferences(
            pt.TealBlock.GetReferencedScratchSlots(actual),
            pt.TealBlock.GetReferencedScratchSlots(expected),
        )

        with pytest.raises(pt.TealInputError):
            element.store_into(abi.Tuple(abi.TupleTypeSpec(elementType)))
示例#9
0
def test_encodeTuple():
    class EncodeTest(NamedTuple):
        types: List[abi.BaseType]
        expected: pt.Expr

    # variables used to construct the tests
    uint64_a = abi.Uint64()
    uint64_b = abi.Uint64()
    uint16_a = abi.Uint16()
    uint16_b = abi.Uint16()
    bool_a = abi.Bool()
    bool_b = abi.Bool()
    tuple_a = abi.Tuple(abi.TupleTypeSpec(abi.BoolTypeSpec(), abi.BoolTypeSpec()))
    dynamic_array_a = abi.DynamicArray(abi.DynamicArrayTypeSpec(abi.Uint64TypeSpec()))
    dynamic_array_b = abi.DynamicArray(abi.DynamicArrayTypeSpec(abi.Uint16TypeSpec()))
    dynamic_array_c = abi.DynamicArray(abi.DynamicArrayTypeSpec(abi.BoolTypeSpec()))
    tail_holder = pt.ScratchVar()
    encoded_tail = pt.ScratchVar()

    tests: List[EncodeTest] = [
        EncodeTest(types=[], expected=pt.Bytes("")),
        EncodeTest(types=[uint64_a], expected=uint64_a.encode()),
        EncodeTest(
            types=[uint64_a, uint64_b],
            expected=pt.Concat(uint64_a.encode(), uint64_b.encode()),
        ),
        EncodeTest(types=[bool_a], expected=bool_a.encode()),
        EncodeTest(
            types=[bool_a, bool_b], expected=_encode_bool_sequence([bool_a, bool_b])
        ),
        EncodeTest(
            types=[bool_a, bool_b, uint64_a],
            expected=pt.Concat(
                _encode_bool_sequence([bool_a, bool_b]), uint64_a.encode()
            ),
        ),
        EncodeTest(
            types=[uint64_a, bool_a, bool_b],
            expected=pt.Concat(
                uint64_a.encode(), _encode_bool_sequence([bool_a, bool_b])
            ),
        ),
        EncodeTest(
            types=[uint64_a, bool_a, bool_b, uint64_b],
            expected=pt.Concat(
                uint64_a.encode(),
                _encode_bool_sequence([bool_a, bool_b]),
                uint64_b.encode(),
            ),
        ),
        EncodeTest(
            types=[uint64_a, bool_a, uint64_b, bool_b],
            expected=pt.Concat(
                uint64_a.encode(), bool_a.encode(), uint64_b.encode(), bool_b.encode()
            ),
        ),
        EncodeTest(types=[tuple_a], expected=tuple_a.encode()),
        EncodeTest(
            types=[uint64_a, tuple_a, bool_a, bool_b],
            expected=pt.Concat(
                uint64_a.encode(),
                tuple_a.encode(),
                _encode_bool_sequence([bool_a, bool_b]),
            ),
        ),
        EncodeTest(
            types=[dynamic_array_a],
            expected=pt.Concat(
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(2),
                    uint16_a.encode(),
                ),
                tail_holder.load(),
            ),
        ),
        EncodeTest(
            types=[uint64_a, dynamic_array_a],
            expected=pt.Concat(
                uint64_a.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(8 + 2),
                    uint16_a.encode(),
                ),
                tail_holder.load(),
            ),
        ),
        EncodeTest(
            types=[uint64_a, dynamic_array_a, uint64_b],
            expected=pt.Concat(
                uint64_a.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(8 + 2 + 8),
                    uint16_a.encode(),
                ),
                uint64_b.encode(),
                tail_holder.load(),
            ),
        ),
        EncodeTest(
            types=[uint64_a, dynamic_array_a, bool_a, bool_b],
            expected=pt.Concat(
                uint64_a.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(8 + 2 + 1),
                    uint16_a.encode(),
                ),
                _encode_bool_sequence([bool_a, bool_b]),
                tail_holder.load(),
            ),
        ),
        EncodeTest(
            types=[uint64_a, dynamic_array_a, uint64_b, dynamic_array_b],
            expected=pt.Concat(
                uint64_a.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(8 + 2 + 8 + 2),
                    uint16_b.set(uint16_a.get() + pt.Len(encoded_tail.load())),
                    uint16_a.encode(),
                ),
                uint64_b.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_b.encode()),
                    tail_holder.store(
                        pt.Concat(tail_holder.load(), encoded_tail.load())
                    ),
                    uint16_a.set(uint16_b),
                    uint16_a.encode(),
                ),
                tail_holder.load(),
            ),
        ),
        EncodeTest(
            types=[
                uint64_a,
                dynamic_array_a,
                uint64_b,
                dynamic_array_b,
                bool_a,
                bool_b,
                dynamic_array_c,
            ],
            expected=pt.Concat(
                uint64_a.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_a.encode()),
                    tail_holder.store(encoded_tail.load()),
                    uint16_a.set(8 + 2 + 8 + 2 + 1 + 2),
                    uint16_b.set(uint16_a.get() + pt.Len(encoded_tail.load())),
                    uint16_a.encode(),
                ),
                uint64_b.encode(),
                pt.Seq(
                    encoded_tail.store(dynamic_array_b.encode()),
                    tail_holder.store(
                        pt.Concat(tail_holder.load(), encoded_tail.load())
                    ),
                    uint16_a.set(uint16_b),
                    uint16_b.set(uint16_a.get() + pt.Len(encoded_tail.load())),
                    uint16_a.encode(),
                ),
                _encode_bool_sequence([bool_a, bool_b]),
                pt.Seq(
                    encoded_tail.store(dynamic_array_c.encode()),
                    tail_holder.store(
                        pt.Concat(tail_holder.load(), encoded_tail.load())
                    ),
                    uint16_a.set(uint16_b),
                    uint16_a.encode(),
                ),
                tail_holder.load(),
            ),
        ),
    ]

    for i, test in enumerate(tests):
        expr = _encode_tuple(test.types)
        assert expr.type_of() == pt.TealType.bytes
        assert not expr.has_return()

        expected, _ = test.expected.__teal__(options)
        expected.addIncoming()
        expected = pt.TealBlock.NormalizeBlocks(expected)

        actual, _ = expr.__teal__(options)
        actual.addIncoming()
        actual = pt.TealBlock.NormalizeBlocks(actual)

        if any(t.type_spec().is_dynamic() for t in test.types):
            with pt.TealComponent.Context.ignoreExprEquality():
                with pt.TealComponent.Context.ignoreScratchSlotEquality():
                    assert actual == expected, "Test at index {} failed".format(i)

            assert pt.TealBlock.MatchScratchSlotReferences(
                pt.TealBlock.GetReferencedScratchSlots(actual),
                pt.TealBlock.GetReferencedScratchSlots(expected),
            )
            continue

        with pt.TealComponent.Context.ignoreExprEquality():
            assert actual == expected, "Test at index {} failed".format(i)