Пример #1
0
    def submit(self, name, code, owner=None, constructor_args={}):
        if self._driver.get_contract(name) is not None:
            raise Exception('Contract already exists.')

        c = ContractingCompiler(module_name=name)

        code_obj = c.parse_to_code(code, lint=True)

        scope = env.gather()
        scope.update({'__contract__': True})
        scope.update(rt.env)

        exec(code_obj, scope)

        if scope.get(config.INIT_FUNC_NAME) is not None:
            if constructor_args is None:
                constructor_args = {}
            scope[config.INIT_FUNC_NAME](**constructor_args)

        now = scope.get('now')
        if now is not None:
            self._driver.set_contract(name=name,
                                      code=code_obj,
                                      owner=owner,
                                      overwrite=False,
                                      timestamp=now)
        else:
            self._driver.set_contract(name=name,
                                      code=code_obj,
                                      owner=owner,
                                      overwrite=False)
Пример #2
0
    def test_token_contract_parses_correctly(self):

        f = open('./test_contracts/currency.s.py')
        code = f.read()
        f.close()

        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)
Пример #3
0
    def test_export_decorator_argument_is_added(self):
        code = '''
@export
def test():
    pass        
'''
        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)
        print(code_str)
Пример #4
0
    def test_private_function_prefixes_properly(self):
        code = '''
def private():
    print('cool')
        '''

        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        self.assertIn('__private', code_str)
Пример #5
0
    def setUp(self):
        self.d = ContractDriver()
        self.d.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.d.set_contract(name='submission', code=contract)
        self.d.commit()

        self.compiler = ContractingCompiler()
Пример #6
0
    def test_visit_assign_variable(self):
        code = '''
v = Variable()
'''
        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        scope = env.gather()

        exec(code_str, scope)

        v = scope['__v']

        self.assertEqual(v._key, '__main__.v')
Пример #7
0
    def test_assign_hash_variable(self):
        code = '''
h = Hash()
        '''
        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        scope = env.gather()

        exec(code_str, scope)

        h = scope['__h']

        self.assertEqual(h._key, '__main__.h')
Пример #8
0
    def test_visit_assign_foreign_variable(self):
        code = '''
fv = ForeignVariable(foreign_contract='scoob', foreign_name='kumbucha')
        '''
        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        scope = env.gather()

        exec(code_str, scope)

        fv = scope['__fv']

        self.assertEqual(fv._key, 'scoob.kumbucha')
Пример #9
0
    def __init__(self,
                 port: int,
                 ctx: zmq.Context = zmq.asyncio.Context(),
                 linger=2000,
                 poll_timeout=2000):
        self.port = port

        self.address = 'tcp://*:{}'.format(port)

        self.ctx = ctx

        self.socket = None

        self.linger = linger
        self.poll_timeout = poll_timeout

        self.running = False

        self.interface = StateInterface(driver=ContractDBDriver(),
                                        compiler=ContractingCompiler(),
                                        engine=Engine(),
                                        blocks=SQLLiteBlockStorageDriver())

        self.log = logging.getLogger('Server')
        self.log.info("Server init")
Пример #10
0
    def test_private_func_call_in_public_func_properly_renamed(self):
        code = '''
@export
def public():
    private('hello')
    
def private(message):
    print(message)
'''

        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        # there should be two private occurances of the method call
        self.assertEqual(len([m.start() for m in re.finditer('__private', code_str)]), 2)
Пример #11
0
    def __init__(self,
                 signer='sys',
                 submission_filename=os.path.join(os.path.dirname(__file__),
                                                  'contracts/submission.s.py'),
                 driver=ContractDriver(),
                 metering=False,
                 compiler=ContractingCompiler(),
                 environment={}):

        self.executor = Executor(metering=metering, driver=driver)
        self.raw_driver = driver
        self.signer = signer
        self.compiler = compiler
        self.submission_filename = submission_filename
        self.environment = environment

        # Seed the genesis contracts into the instance
        with open(self.submission_filename) as f:
            contract = f.read()

        self.raw_driver.set_contract(name='submission', code=contract)

        self.raw_driver.commit()

        self.submission_contract = self.get_contract('submission')
Пример #12
0
    def test_construct_renames_properly(self):
        code = '''
@construct
def seed():
    print('yes')

@export
def hello():
    print('no')
    
def goodbye():
    print('idk')
        '''

        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)
Пример #13
0
    def test_private_func_call_in_other_private_functions(self):
        code = '''
def a():
    b()
    
def b():
    c()
    
def c():
    e()
    
def d():
    print('hello')
    
def e():
    d()        
'''
        c = ContractingCompiler()
        comp = c.parse(code, lint=False)
        code_str = astor.to_source(comp)

        self.assertEqual(len([m.start() for m in re.finditer(config.PRIVATE_METHOD_PREFIX, code_str)]), 9)
Пример #14
0
    def setUp(self):
        self.rpc = rpc.StateInterface(driver=ContractDBDriver(),
                                      engine=Engine(),
                                      compiler=ContractingCompiler(),
                                      blocks=SQLLiteBlockStorageDriver())

        self.rpc.driver.flush()

        with open('../../contractdb/contracts/submission.s.py') as f:
            contract = f.read()

        self.rpc.driver.set_contract(name='submission', code=contract)

        self.e = Executor(currency_contract='erc20_clone', metering=False)

        self.e.execute(**TEST_SUBMISSION_KWARGS,
                       kwargs=submission_kwargs_for_file(
                           './test_sys_contracts/currency.s.py'))
Пример #15
0
class TestParser(TestCase):
    def setUp(self):
        self.compiler = ContractingCompiler()

    def test_methods_for_contract_single_function(self):
        code = '''
@export
def test_func(arg: str, arg2: int):
    return arg, arg2
        '''

        compiled = self.compiler.parse_to_code(code)

        expected = [{
            'name': 'test_func',
            'arguments': [
                {
                    'name': 'arg',
                    'type': 'str'
                },
                {
                    'name': 'arg2',
                    'type': 'int'
                }
            ]
        }]

        got = parser.methods_for_contract(compiled)

        self.assertListEqual(expected, got)

    def test_methods_for_contract_multiple_functions_and_privates(self):
        code = '''
@export
def test_func(arg: str, arg2: int):
    return arg, arg2
    
@export
def another_one(something: Any, something_else: dict):
    a = 123
    b = 456
    return add(a, b)
    
def add(a, b):
    return a + b
'''
        compiled = self.compiler.parse_to_code(code)

        expected = [{
            'name': 'test_func',
            'arguments': [
                {
                    'name': 'arg',
                    'type': 'str'
                },
                {
                    'name': 'arg2',
                    'type': 'int'
                }
            ],
        },
        {
            'name': 'another_one',
            'arguments': [
                {
                    'name': 'something',
                    'type': 'Any'
                },
                {
                    'name': 'something_else',
                    'type': 'dict'
                }
            ]
        }]

        got = parser.methods_for_contract(compiled)

        self.assertListEqual(expected, got)

    def test_variables_for_contract_passes_election_house(self):
        code = '''
# Convenience
I = importlib

#Policies
policies = Hash()

# Policy interface
policy_interface = [
    I.Func('vote', args=('vk', 'obj')),
    I.Func('current_value')
]

@export
def register_policy(contract: str):
    if policies[contract] is None:
        # Attempt to import the contract to make sure it is already submitted
        p = I.import_module(contract)

        # Assert ownership is election_house and interface is correct
        assert I.owner_of(p) == ctx.this, \
            'Election house must control the policy contract!'

        assert I.enforce_interface(p, policy_interface), \
            'Policy contract does not follow the correct interface'

        policies[contract] = True
    else:
        raise Exception('Policy already registered')

@export
def current_value_for_policy(policy: str):
    assert policies.get(policy) is not None, 'Invalid policy.'
    p = I.import_module(policy)

    return p.current_value()

@export
def vote(policy: str, value: Any):
    # Verify policy has been registered
    assert policies.get(policy) is not None, 'Invalid policy.'
    p = I.import_module(policy)

    p.vote(vk=ctx.caller, obj=value)
    '''

        compiled = self.compiler.parse_to_code(code)

        got = parser.variables_for_contract(compiled)

        expected = {
            'variables': [],
            'hashes': ['policies']
        }

        self.assertDictEqual(got, expected)

    def test_variables_for_contract_multiple_variables(self):
        code = '''
v1 = Variable()
v2 = Variable()
v3 = Variable()

@export
def something():
   return 1
        '''

        compiled = self.compiler.parse_to_code(code)

        got = parser.variables_for_contract(compiled)

        expected = {
            'variables': ['v1', 'v2', 'v3'],
            'hashes': []
        }

        self.assertDictEqual(got, expected)

    def test_variables_for_contract_multiple_hashes(self):
        code = '''
h1 = Hash()
h2 = Hash()
h3 = Hash()

@export
def something():
   return 1
        '''

        compiled = self.compiler.parse_to_code(code)

        got = parser.variables_for_contract(compiled)

        expected = {
            'variables': [],
            'hashes': ['h1', 'h2', 'h3']
        }

        self.assertDictEqual(got, expected)

    def test_variables_mix(self):
        code = '''
v1 = Variable()
v2 = Variable()
v3 = Variable()
h1 = Hash()
h2 = Hash()
h3 = Hash()

@export
def something():
   return 1
        '''

        compiled = self.compiler.parse_to_code(code)

        got = parser.variables_for_contract(compiled)

        expected = {
            'variables': ['v1', 'v2', 'v3'],
            'hashes': ['h1', 'h2', 'h3']
        }

        self.assertDictEqual(got, expected)
Пример #16
0
class TestExecutor(TestCase):
    def setUp(self):
        self.d = ContractDriver()
        self.d.flush()

        with open('../../contracting/contracts/submission.s.py') as f:
            contract = f.read()

        self.d.set_contract(name='submission', code=contract)
        self.d.commit()

        self.compiler = ContractingCompiler()

    def tearDown(self):
        self.d.flush()

    def test_submission(self):
        e = Executor(metering=False)

        code = '''@export
def d():
    a = 1
    return 1            
'''

        kwargs = {'name': 'stubucks', 'code': code}

        e.execute(**TEST_SUBMISSION_KWARGS, kwargs=kwargs, auto_commit=True)

        self.compiler.module_name = 'stubucks'
        new_code = self.compiler.parse_to_code(code)

        self.assertEqual(self.d.get_contract('stubucks'), new_code)

    def test_submission_then_function_call(self):
        e = Executor(metering=False)

        code = '''@export
def d():
    return 1            
'''

        kwargs = {'name': 'stubuckz', 'code': code}

        e.execute(**TEST_SUBMISSION_KWARGS, kwargs=kwargs)
        output = e.execute(sender='stu',
                           contract_name='stubuckz',
                           function_name='d',
                           kwargs={})

        self.assertEqual(output['result'], 1)
        self.assertEqual(output['status_code'], 0)

    def test_kwarg_helper(self):
        k = submission_kwargs_for_file(
            './test_contracts/test_orm_variable_contract.s.py')

        code = '''v = Variable()

@export
def set_v(i: int):
    v.set(i)

@export
def get_v():
    return v.get()
'''

        self.assertEqual(k['name'], 'test_orm_variable_contract')
        self.assertEqual(k['code'], code)

    def test_orm_variable_sets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_variable_contract.s.py'),
                  auto_commit=True)

        e.execute('stu',
                  'test_orm_variable_contract',
                  'set_v',
                  kwargs={'i': 1000},
                  auto_commit=True)

        i = self.d.get('test_orm_variable_contract.v')
        self.assertEqual(i, 1000)

    def test_orm_variable_gets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_variable_contract.s.py'))

        res = e.execute('stu',
                        'test_orm_variable_contract',
                        'get_v',
                        kwargs={})

        self.assertEqual(res['result'], None)

    def test_orm_variable_gets_and_sets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_variable_contract.s.py'))

        e.execute('stu',
                  'test_orm_variable_contract',
                  'set_v',
                  kwargs={'i': 1000})
        res = e.execute('stu',
                        'test_orm_variable_contract',
                        'get_v',
                        kwargs={})

        self.assertEqual(res['result'], 1000)

    def test_orm_hash_sets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_hash_contract.s.py'),
                  auto_commit=True)

        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'key1',
                      'v': 1234
                  },
                  auto_commit=True)
        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'another_key',
                      'v': 9999
                  },
                  auto_commit=True)

        key1 = self.d.get('test_orm_hash_contract.h:key1')
        another_key = self.d.get('test_orm_hash_contract.h:another_key')

        self.assertEqual(key1, 1234)
        self.assertEqual(another_key, 9999)

    def test_orm_hash_gets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_hash_contract.s.py'))

        res = e.execute('stu',
                        'test_orm_hash_contract',
                        'get_h',
                        kwargs={'k': 'test'})

        self.assertEqual(res['result'], None)

    def test_orm_hash_gets_and_sets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_hash_contract.s.py'))

        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'key1',
                      'v': 1234
                  })
        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'another_key',
                      'v': 9999
                  })

        key1 = e.execute('stu',
                         'test_orm_hash_contract',
                         'get_h',
                         kwargs={'k': 'key1'})
        another_key = e.execute('stu',
                                'test_orm_hash_contract',
                                'get_h',
                                kwargs={'k': 'another_key'})

        self.assertEqual(key1['result'], 1234)
        self.assertEqual(another_key['result'], 9999)

    def test_orm_foreign_variable_sets_in_contract_doesnt_work(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_variable_contract.s.py'))
        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_foreign_key_contract.s.py'))

        e.execute('stu',
                  'test_orm_variable_contract',
                  'set_v',
                  kwargs={'i': 1000})

        # this should fail
        status = e.execute('stu',
                           'test_orm_foreign_key_contract',
                           'set_fv',
                           kwargs={'i': 999})

        self.assertEqual(status['status_code'], 1)

        i = e.execute('stu', 'test_orm_variable_contract', 'get_v', kwargs={})
        self.assertEqual(i['result'], 1000)

    def test_orm_foreign_variable_gets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_variable_contract.s.py'))
        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_foreign_key_contract.s.py'))

        e.execute('stu',
                  'test_orm_variable_contract',
                  'set_v',
                  kwargs={'i': 424242})

        # this should fail
        i = e.execute('stu',
                      'test_orm_foreign_key_contract',
                      'get_fv',
                      kwargs={})

        self.assertEqual(i['result'], 424242)

    def test_orm_foreign_hash_sets_in_contract_doesnt_work(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_hash_contract.s.py'),
                  auto_commit=True)
        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_foreign_hash_contract.s.py'),
                  auto_commit=True)

        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'key1',
                      'v': 1234
                  },
                  auto_commit=True)
        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'another_key',
                      'v': 9999
                  },
                  auto_commit=True)

        status_1 = e.execute('stu',
                             'test_orm_foreign_hash_contract',
                             'set_fh',
                             kwargs={
                                 'k': 'key1',
                                 'v': 5555
                             },
                             auto_commit=True)
        status_2 = e.execute('stu',
                             'test_orm_foreign_hash_contract',
                             'set_fh',
                             kwargs={
                                 'k': 'another_key',
                                 'v': 1000
                             },
                             auto_commit=True)

        key1 = self.d.get('test_orm_hash_contract.h:key1')
        another_key = self.d.get('test_orm_hash_contract.h:another_key')

        self.assertEqual(key1, 1234)
        self.assertEqual(another_key, 9999)
        self.assertEqual(status_1['status_code'], 1)
        self.assertEqual(status_2['status_code'], 1)

    def test_orm_foreign_hash_gets_and_sets_in_contract(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_hash_contract.s.py'))

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/test_orm_foreign_hash_contract.s.py'))

        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'key1',
                      'v': 1234
                  })
        e.execute('stu',
                  'test_orm_hash_contract',
                  'set_h',
                  kwargs={
                      'k': 'another_key',
                      'v': 9999
                  })

        key1 = e.execute('stu',
                         'test_orm_foreign_hash_contract',
                         'get_fh',
                         kwargs={'k': 'key1'})
        another_key = e.execute('stu',
                                'test_orm_foreign_hash_contract',
                                'get_fh',
                                kwargs={'k': 'another_key'})

        self.assertEqual(key1['result'], 1234)
        self.assertEqual(another_key['result'], 9999)

    def test_orm_contract_not_accessible(self):
        e = Executor(metering=False)

        output = e.execute(
            **TEST_SUBMISSION_KWARGS,
            kwargs=submission_kwargs_for_file(
                './test_contracts/test_orm_no_contract_access.s.py'))

        self.assertIsInstance(output['result'], Exception)

    def test_construct_function_sets_properly(self):
        e = Executor(metering=False)

        r = e.execute(
            **TEST_SUBMISSION_KWARGS,
            kwargs=submission_kwargs_for_file(
                './test_contracts/test_construct_function_works.s.py'))

        output = e.execute('stu',
                           'test_construct_function_works',
                           'get',
                           kwargs={})

        self.assertEqual(output['result'], 42)

    def test_import_exported_function_works(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/import_this.s.py'))

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/importing_that.s.py'))

        output = e.execute('stu', 'importing_that', 'test', kwargs={})

        self.assertEqual(output['result'], 12345 - 1000)

    def test_arbitrary_environment_passing_works_via_executor(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/i_use_env.s.py'))

        this_is_a_passed_in_variable = 555

        env = {'this_is_a_passed_in_variable': this_is_a_passed_in_variable}

        output = e.execute('stu',
                           'i_use_env',
                           'env_var',
                           kwargs={},
                           environment=env)

        self.assertEqual(output['result'], this_is_a_passed_in_variable)

    def test_arbitrary_environment_passing_fails_if_not_passed_correctly(self):
        e = Executor(metering=False)

        e.execute(**TEST_SUBMISSION_KWARGS,
                  kwargs=submission_kwargs_for_file(
                      './test_contracts/i_use_env.s.py'))

        this_is_a_passed_in_variable = 555

        env = {
            'this_is_another_passed_in_variable': this_is_a_passed_in_variable
        }

        output = e.execute('stu',
                           'i_use_env',
                           'env_var',
                           kwargs={},
                           environment=env)

        self.assertEqual(output['status_code'], 1)
Пример #17
0
 def __init__(self, compiler=ContractingCompiler()):
     self.compiler = compiler
Пример #18
0
 def setUp(self):
     self.compiler = ContractingCompiler()