Example #1
0
def test_constants_fail(bad_code):
    if isinstance(bad_code, tuple):
        with raises(bad_code[1]):
            compiler.compile_code(bad_code[0])
    else:
        with raises(StructureException):
            compiler.compile_code(bad_code)
Example #2
0
def test_varname_validity_fail(bad_code):
    if isinstance(bad_code, tuple):
        with raises(bad_code[1]):
            compiler.compile_code(bad_code[0])
    else:
        with raises(EventDeclarationException):
            compiler.compile_code(bad_code)
Example #3
0
def test_tuple_assign_fail(bad_code):
    if isinstance(bad_code, tuple):
        with raises(bad_code[1]):
            compiler.compile_code(bad_code[0])
    else:
        with raises(TypeMismatch):
            compiler.compile_code(bad_code)
Example #4
0
def test_as_wei_fail(bad_code):
    if isinstance(bad_code, tuple):
        with raises(bad_code[1]):
            compiler.compile_code(bad_code[0])
    else:
        with raises(VariableDeclarationException):
            compiler.compile_code(bad_code)
Example #5
0
def test_chain_fail(bad_code):

    if isinstance(bad_code, tuple):
        with raises(bad_code[1]):
            compiler.compile_code(bad_code[0], evm_version="istanbul")
    else:
        with raises(TypeMismatch):
            compiler.compile_code(bad_code, evm_version="istanbul")
Example #6
0
def test_undef_toplevel():
    code = """
@public
def foo():
    x = bar(55)
    """
    with raises(StructureException) as ex:
        compiler.compile_code(code)
    assert "Not a top-level function: bar" in str(ex.value)
Example #7
0
def test_json_interface_implements(type_str):
    code = interface_test_code.format(type_str)

    abi = compile_code(code, ['abi'])['abi']
    code = f"import jsonabi as jsonabi\nimplements: jsonabi\n{code}"
    compile_code(code,
                 interface_codes={'jsonabi': {
                     'type': 'json',
                     'code': abi
                 }})
Example #8
0
def test_evm_version(evm_version):
    code = """
@public
def foo():
    a: uint256 = chain.id
    """

    if EVM_VERSIONS[evm_version] < 2:
        with raises(EvmVersionException):
            compiler.compile_code(code, evm_version=evm_version)
    else:
        compiler.compile_code(code, evm_version=evm_version)
Example #9
0
def test_undef_suggestion():
    code = """
@public
def bar(x: int128) -> int128:
    return 3 * x

@public
def foo() -> int128:
    return bar(20)
    """
    with raises(StructureException) as ex:
        compiler.compile_code(code)
    assert "Not a top-level function: bar" in str(ex.value)
    assert "Did you mean self.bar?" in str(ex.value)
Example #10
0
def test_external_interface_parsing(assert_compile_failed):
    interface_code = """
@public
def foo() -> uint256:
    pass

@public
def bar() -> uint256:
    pass
    """

    interface_codes = {
        'FooBarInterface': {
            'type': 'srilang',
            'code': interface_code
        }
    }

    code = """
import a as FooBarInterface

implements: FooBarInterface

@public
def foo() -> uint256:
    return 1

@public
def bar() -> uint256:
    return 2
    """

    assert compile_code(code, interface_codes=interface_codes)

    not_implemented_code = """
import a as FooBarInterface

implements: FooBarInterface

@public
def foo() -> uint256:
    return 1

    """

    assert_compile_failed(
        lambda: compile_code(not_implemented_code,
                             interface_codes=interface_codes),
        StructureException)
Example #11
0
def test_imports_and_implements_within_interface():
    interface_code = """
from srilang.interfaces import ERC20
import foo.bar as Baz

implements: Baz

@public
def foobar():
    pass
"""

    code = """
import foo as Foo

implements: Foo

@public
def foobar():
    pass
"""

    assert compiler.compile_code(
        code,
        interface_codes={'Foo': {
            'type': "srilang",
            'code': interface_code
        }}) is not None
Example #12
0
def _get_contract(w3, source_code, *args, **kwargs):
    out = compiler.compile_code(
        source_code,
        ['abi', 'bytecode'],
        interface_codes=kwargs.pop('interface_codes', None),
        evm_version=kwargs.pop('evm_version', None),
    )
    LARK_GRAMMAR.parse(source_code + "\n")  # Test grammar.
    abi = out['abi']
    bytecode = out['bytecode']
    value = kwargs.pop('value_in_eth',
                       0) * 10**18  # Handle deploying with an eth value.
    c = w3.eth.contract(abi=abi, bytecode=bytecode)
    deploy_transaction = c.constructor(*args)
    tx_info = {
        'from': w3.eth.accounts[0],
        'value': value,
        'gasPrice': 0,
    }
    tx_info.update(kwargs)
    tx_hash = deploy_transaction.transact(tx_info)
    address = w3.eth.getTransactionReceipt(tx_hash)['contractAddress']
    contract = w3.eth.contract(
        address,
        abi=abi,
        bytecode=bytecode,
        ContractFactoryClass=srilangContract,
    )
    return contract
Example #13
0
def test_get_extcodehash(get_contract, evm_version):
    code = """
a: address

@public
def __init__():
    self.a = self

@public
def foo(x: address) -> bytes32:
    return x.codehash

@public
def foo2(x: address) -> bytes32:
    b: address = x
    return b.codehash

@public
def foo3() -> bytes32:
    return self.codehash

@public
def foo4() -> bytes32:
    return self.a.codehash
    """

    if evm_version in ("byzantium", "atlantis"):
        with pytest.raises(EvmVersionException):
            compile_code(code, evm_version=evm_version)
        return

    compiled = compile_code(code, ['bytecode_runtime'], evm_version=evm_version)
    bytecode = bytes.fromhex(compiled['bytecode_runtime'][2:])
    hash_ = keccak256(bytecode)

    c = get_contract(code, evm_version=evm_version)

    assert c.foo(c.address) == hash_
    assert not int(c.foo("0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF").hex(), 16)

    assert c.foo2(c.address) == hash_
    assert not int(c.foo2("0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF").hex(), 16)

    assert c.foo3() == hash_
    assert c.foo4() == hash_
Example #14
0
def test_bitwise_opcodes(evm_version):
    opcodes = compile_code(code, ['opcodes'],
                           evm_version=evm_version)['opcodes']
    if evm_version in ("byzantium", "atlantis"):
        assert "SHL" not in opcodes
        assert "SHR" not in opcodes
    else:
        assert "SHL" in opcodes
        assert "SHR" in opcodes
Example #15
0
def test_ast_to_dict_node_id():
    code = """
@public
def test() -> int128:
    a: uint256 = 100
    return 123
    """
    dict_out = compiler.compile_code(code, ['ast_dict'])
    node_ids = get_node_ids(dict_out)

    assert len(node_ids) == len(set(node_ids))
Example #16
0
def test_basic_interface_implements(assert_compile_failed):
    code = """
from srilang.interfaces import ERC20

implements: ERC20


@public
def test() -> bool:
    return True
    """

    assert_compile_failed(lambda: compile_code(code), StructureException)
Example #17
0
def test_self_interface_cannot_compile(assert_compile_failed):
    code = """
contract Bar:
    def foo() -> uint256: constant

@public
def foo() -> uint256 :
    return 42

@public
def bar() -> uint256:
    return Bar(self).foo()
"""
    assert_compile_failed(lambda: compile_code(code), StructureException)
Example #18
0
def test_constant_folds(search_for_sublist):
    some_prime = 10013677
    code = f"""
SOME_CONSTANT: constant(uint256) = 11 + 1
SOME_PRIME: constant(uint256) = {some_prime}

@public
def test() -> uint256:
    # calculate some constant which is really unlikely to be randomly
    # in bytecode
    return 2**SOME_CONSTANT * SOME_PRIME
    """

    lll = compile_code(code, ['ir'])['ir']
    assert search_for_sublist(lll, ['mstore', [0], [2**12 * some_prime]])
Example #19
0
def test_jump_map():
    source_map = compile_code(TEST_CODE, ['source_map'])['source_map']
    pos_map = source_map['pc_pos_map']
    jump_map = source_map['pc_jump_map']

    assert len([v for v in jump_map.values() if v == "o"]) == 3
    assert len([v for v in jump_map.values() if v == "i"]) == 2

    code_lines = [i + "\n" for i in TEST_CODE.split("\n")]
    for pc in [k for k, v in jump_map.items() if v == "o"]:
        lineno, col_offset, _, end_col_offset = pos_map[pc]
        assert code_lines[lineno -
                          1][col_offset:end_col_offset].startswith("return")

    for pc in [k for k, v in jump_map.items() if v == "i"]:
        lineno, col_offset, _, end_col_offset = pos_map[pc]
        assert code_lines[lineno -
                          1][col_offset:end_col_offset].startswith("self.")
Example #20
0
def test_method_identifiers():
    code = """
x: public(int128)

@public
def foo(x: uint256) -> bytes[100]:
    return b"hello"
    """

    out = compile_code(
        code,
        output_formats=['method_identifiers'],
    )

    assert out['method_identifiers'] == {
        'foo(uint256)': '0x2fbebd38',
        'x()': '0xc55699c'
    }
Example #21
0
def test_json_interface_calls(get_contract, type_str, value):
    code = interface_test_code.format(type_str)

    abi = compile_code(code, ['abi'])['abi']
    c1 = get_contract(code)

    code = f"""
import jsonabi as jsonabi

@public
@constant
def test_call(a: address, b: {type_str}) -> {type_str}:
    return jsonabi(a).test_json(b)
    """
    c2 = get_contract(
        code, interface_codes={'jsonabi': {
            'type': 'json',
            'code': abi
        }})
    assert c2.test_call(c1.address, value) == value
Example #22
0
def test_struct_return_abi(get_contract_with_gas_estimation):
    code = """
struct Voter:
    weight: int128
    voted: bool

@public
def test() -> Voter:
    a: Voter = Voter({weight: 123, voted: True})
    return a
    """

    out = compile_code(code, ['abi'])
    abi = out['abi'][0]

    assert abi['name'] == 'test'

    c = get_contract_with_gas_estimation(code)

    assert c.test() == (123, True)
Example #23
0
def test_basic_extract_interface():
    code = """
# Events

Transfer: event({_from: address, _to: address, _value: uint256})

# Functions

@constant
@public
def allowance(_owner: address, _spender: address) -> (uint256, uint256):
    return 1, 2
    """

    out = compile_code(code, ['interface'])
    out = out['interface']
    code_pass = '******'.join(code.split('\n')[:-2] +
                          ['    pass'])  # replace with a pass statement.

    assert code_pass.strip() == out.strip()
Example #24
0
def test_pos_map_offsets():
    source_map = compile_code(TEST_CODE, ['source_map'])['source_map']
    expanded = expand_source_map(source_map['pc_pos_map_compressed'])

    pc_iter = iter(source_map['pc_pos_map'][i]
                   for i in sorted(source_map['pc_pos_map']))
    jump_iter = iter(source_map['pc_jump_map'][i]
                     for i in sorted(source_map['pc_jump_map']))
    code_lines = [i + "\n" for i in TEST_CODE.split("\n")]

    for item in expanded:
        if item[-1] is not None:
            assert next(jump_iter) == item[-1]

        if item[:2] != [-1, -1]:
            start, length = item[:2]
            lineno, col_offset, end_lineno, end_col_offset = next(pc_iter)
            assert code_lines[lineno - 1][col_offset] == TEST_CODE[start]
            assert length == (
                sum(len(i)
                    for i in code_lines[lineno - 1:end_lineno]) - col_offset -
                (len(code_lines[end_lineno - 1]) - end_col_offset))
Example #25
0
def test_basic_ast():
    code = """
a: int128
    """
    dict_out = compiler.compile_code(code, ['ast_dict'])
    assert dict_out['ast_dict']['ast']['body'][0] == {
        'annotation': {
            'ast_type': 'Name',
            'col_offset': 3,
            'end_col_offset': 9,
            'end_lineno': 2,
            'id': 'int128',
            'lineno': 2,
            'node_id': 4,
            'src': "4:6:0",
        },
        'ast_type': 'AnnAssign',
        'col_offset': 0,
        'end_col_offset': 9,
        'end_lineno': 2,
        'lineno': 2,
        'node_id': 1,
        'simple': 1,
        'src': '1:9:0',
        'target': {
            'ast_type': 'Name',
            'col_offset': 0,
            'end_col_offset': 1,
            'end_lineno': 2,
            'id': 'a',
            'lineno': 2,
            'node_id': 2,
            'src': '1:1:0',
        },
        'value': None
    }
Example #26
0
def test_varname_validity_success(good_code):
    assert compiler.compile_code(good_code) is not None
Example #27
0
def test_varname_validity_fail(bad_code):
    with raises(FunctionDeclarationException):
        compiler.compile_code(bad_code)
Example #28
0
def test_block_fail(bad_code):

    with raises(TypeMismatch):
        compiler.compile_code(bad_code)
Example #29
0
def test_syntax_exception(bad_code):
    with raises(SyntaxException):
        compiler.compile_code(bad_code)
Example #30
0
def test_block_success(good_code):
    assert compiler.compile_code(good_code) is not None