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)
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)
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)
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)
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 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')
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')
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')
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")
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)
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')
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)
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)
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'))
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)
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)
def __init__(self, compiler=ContractingCompiler()): self.compiler = compiler
def setUp(self): self.compiler = ContractingCompiler()