Ejemplo n.º 1
0
def return_contract():  # pragma: no cover
    client = ContractingClient()
    return client.closure_to_code_string(dex)[0]  # Returns code
Ejemplo n.º 2
0
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        self.client.submit(election_house, name='election_house2')

        self.election_house = self.client.get_contract(name='election_house2')
Ejemplo n.º 3
0
class TestRewards(TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.rewards = rewards.RewardManager()

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

    def sync(self):
        sync.setup_genesis_contracts(['stu', 'raghu', 'steve'],
                                     ['tejas', 'alex2'],
                                     client=self.client)

    def test_contract_exists_false_before_sync(self):
        self.assertFalse(
            self.rewards.contract_exists('stamp_cost', self.client))

    def test_contract_exists_true_after_sync(self):
        # Sync contracts
        self.sync()
        self.assertTrue(self.rewards.contract_exists('stamp_cost',
                                                     self.client))

    def test_is_setup_false_before_sync(self):
        self.assertFalse(self.rewards.is_setup(self.client))

    def test_is_setup_true_after_sync(self):
        self.sync()
        self.assertTrue(self.rewards.is_setup(self.client))

    def test_add_to_balance_if_none_sets(self):
        self.rewards.add_to_balance('stu', 123, self.client)
        bal = self.client.get_var('currency',
                                  variable='balances',
                                  arguments=['stu'])
        self.assertEqual(bal, 123)

    def test_add_to_balance_twice_sets_accordingly(self):
        self.rewards.add_to_balance('stu', 123, self.client)
        bal = self.client.get_var('currency',
                                  variable='balances',
                                  arguments=['stu'])
        self.assertEqual(bal, 123)

        self.rewards.add_to_balance('stu', 123, self.client)
        bal = self.client.get_var('currency',
                                  variable='balances',
                                  arguments=['stu'])
        self.assertEqual(bal, 246)

    def test_calculate_rewards_returns_accurate_amounts_per_participant_group(
            self):
        self.sync()
        self.client.set_var(contract='rewards',
                            variable='S',
                            arguments=['value'],
                            value=[0.4, 0.3, 0.1, 0.1, 0.1])

        m, d, f, mapping = self.rewards.calculate_all_rewards(
            client=self.client, block=BLOCK)

        reconstructed = (m * 3) + (d * 2) + (f * 1) + (f * 1) + (f * 1)

        self.assertAlmostEqual(reconstructed,
                               self.rewards.stamps_in_block(BLOCK))

    def test_calculate_participant_reward_shaves_off_dust(self):
        rounded_reward = self.rewards.calculate_participant_reward(
            participant_ratio=1,
            number_of_participants=1,
            total_stamps_to_split=1.0000000000001)

        self.assertEqual(rounded_reward, 1)

    def test_distribute_rewards_adds_to_all_wallets(self):
        self.sync()
        self.client.set_var(contract='rewards',
                            variable='S',
                            arguments=['value'],
                            value=[0.4, 0.3, 0.1, 0.1, 0.1])
        self.client.set_var(contract='foundation',
                            variable='owner',
                            value='xxx')

        self.client.set_var(contract='stamp_cost',
                            variable='S',
                            arguments=['value'],
                            value=100)

        self.client.set_var(contract='thing_1',
                            variable='__developer__',
                            value='stu2')

        self.client.set_var(contract='thing_2',
                            variable='__developer__',
                            value='jeff')

        self.client.set_var(contract='thing_3',
                            variable='__developer__',
                            value='alex')

        total_tau_to_split = 4900

        m, d, f, mapping = self.rewards.calculate_all_rewards(
            client=self.client, block=BLOCK)

        self.rewards.distribute_rewards(m, d, f, mapping, client=self.client)

        masters = self.client.get_var(contract='masternodes',
                                      variable='S',
                                      arguments=['members'])
        delegates = self.client.get_var(contract='delegates',
                                        variable='S',
                                        arguments=['members'])

        for mn in masters:
            current_balance = self.client.get_var(contract='currency',
                                                  variable='balances',
                                                  arguments=[mn],
                                                  mark=False)
            self.assertEqual(current_balance, m / 100)

        for dl in delegates:
            current_balance = self.client.get_var(contract='currency',
                                                  variable='balances',
                                                  arguments=[dl],
                                                  mark=False)
            self.assertEqual(current_balance, d / 100)

        current_balance = self.client.get_var(contract='currency',
                                              variable='balances',
                                              arguments=['xxx'],
                                              mark=False)
        self.assertEqual(current_balance, f / 100)

    def test_stamps_in_block(self):
        block = {
            'number':
            2,
            'subblocks': [{
                'transactions': [{
                    'stamps_used': 1000
                }, {
                    'stamps_used': 2000
                }, {
                    'stamps_used': 3000
                }]
            }, {
                'transactions': [{
                    'stamps_used': 4500
                }, {
                    'stamps_used': 1250
                }, {
                    'stamps_used': 2750
                }]
            }]
        }

        self.assertEqual(self.rewards.stamps_in_block(block), 14500)

    def test_issue_rewards_full_loop_works(self):
        self.sync()
        self.client.set_var(contract='rewards',
                            variable='S',
                            arguments=['value'],
                            value=[0.4, 0.3, 0.1, 0.1, 0.1])
        self.client.set_var(contract='foundation',
                            variable='owner',
                            value='xxx')
        self.client.set_var(contract='stamp_cost',
                            variable='S',
                            arguments=['value'],
                            value=100)

        self.client.set_var(contract='thing_1',
                            variable='__developer__',
                            value='stu2')

        self.client.set_var(contract='thing_2',
                            variable='__developer__',
                            value='jeff')

        self.client.set_var(contract='thing_3',
                            variable='__developer__',
                            value='alex')

        block = {
            'number':
            1,
            'subblocks': [{
                'transactions': [{
                    'stamps_used': 1000,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_1'
                        }
                    }
                }, {
                    'stamps_used': 2000,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_2'
                        }
                    }
                }, {
                    'stamps_used': 3000,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_3'
                        }
                    }
                }]
            }, {
                'transactions': [{
                    'stamps_used': 4500,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_1'
                        }
                    }
                }, {
                    'stamps_used': 1250,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_1'
                        }
                    }
                }, {
                    'stamps_used': 2750,
                    'transaction': {
                        'payload': {
                            'contract': 'thing_2'
                        }
                    }
                }]
            }]
        }

        # tau to distribute should be 145

        stamps = self.rewards.stamps_in_block(block)

        tau = stamps / 100

        self.assertEqual(tau, 145)

        self.rewards.issue_rewards(block, client=self.client)

        # Stu is owed: 6750 stamps / 100 / 3 =
        # Jeff is owed: 4750 stamps / 100 / 3= 47.5
        # Alex is owed:

        m, d, f, mapping = self.rewards.calculate_all_rewards(
            client=self.client, block=block)

        masters = self.client.get_var(contract='masternodes',
                                      variable='S',
                                      arguments=['members'])
        delegates = self.client.get_var(contract='delegates',
                                        variable='S',
                                        arguments=['members'])

        for mn in masters:
            current_balance = self.client.get_var(contract='currency',
                                                  variable='balances',
                                                  arguments=[mn],
                                                  mark=False)
            self.assertEqual(current_balance, m / 100)

        for dl in delegates:
            current_balance = self.client.get_var(contract='currency',
                                                  variable='balances',
                                                  arguments=[dl],
                                                  mark=False)
            self.assertEqual(current_balance, d / 100)

        current_balance = self.client.get_var(contract='currency',
                                              variable='balances',
                                              arguments=['xxx'],
                                              mark=False)
        self.assertEqual(current_balance, f / 100)

        for dev in mapping.keys():
            current_balance = self.client.get_var(contract='currency',
                                                  variable='balances',
                                                  arguments=[dev],
                                                  mark=False)

            self.assertAlmostEqual(current_balance, mapping[dev] / 100)
Ejemplo n.º 4
0
class TestAuthenticator(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.w = Wallet()

        masternodes = [
            Wallet().verifying_key().hex(),
            Wallet().verifying_key().hex(),
            Wallet().verifying_key().hex(),
        ]
        delegates = [
            Wallet().verifying_key().hex(),
            Wallet().verifying_key().hex(),
            Wallet().verifying_key().hex(),
        ]

        self.c = ContractingClient()
        self.c.flush()

        sync.submit_from_genesis_json_file(cilantro_ee.contracts.__path__[0] +
                                           '/genesis.json',
                                           client=self.c)
        sync.submit_node_election_contracts(initial_masternodes=masternodes,
                                            boot_mns=1,
                                            initial_delegates=delegates,
                                            boot_dels=1,
                                            client=self.c)

        self.s = SocketAuthenticator(ctx=self.ctx)

    def tearDown(self):
        self.ctx.destroy()

        self.c.flush()

    def test_double_init(self):
        w = Wallet()

        with self.assertRaises(Exception):
            b = SocketAuthenticator(ctx=self.ctx)

    def test_add_verifying_key_as_bytes(self):
        sk = SigningKey.generate()

        self.s.add_verifying_key(sk.verify_key.encode())

        self.assertTrue(
            os.path.exists(
                os.path.join(self.s.cert_dir,
                             f'{sk.verify_key.encode().hex()}.key')))

    def test_sync_certs_creates_files(self):
        self.s.sync_certs()

        for m in self.s.contacts.masternodes:
            self.assertTrue(
                os.path.exists(os.path.join(self.s.cert_dir, f'{m}.key')))

        for d in self.s.contacts.delegates:
            self.assertTrue(
                os.path.exists(os.path.join(self.s.cert_dir, f'{d}.key')))

    def test_add_governance_sockets_all_creates_files(self):
        fake_mns = [
            Wallet().verifying_key(),
            Wallet().verifying_key(),
            Wallet().verifying_key()
        ]
        fake_od_m = Wallet().verifying_key()

        fake_dels = [Wallet().verifying_key(), Wallet().verifying_key()]
        fake_od_d = Wallet().verifying_key()

        self.s.add_governance_sockets(masternode_list=fake_mns,
                                      on_deck_masternode=fake_od_m,
                                      delegate_list=fake_dels,
                                      on_deck_delegate=fake_od_d)

        for m in fake_mns:
            self.assertTrue(
                os.path.exists(os.path.join(self.s.cert_dir,
                                            f'{m.hex()}.key')))

        for d in fake_dels:
            self.assertTrue(
                os.path.exists(os.path.join(self.s.cert_dir,
                                            f'{d.hex()}.key')))

        self.assertTrue(
            os.path.exists(
                os.path.join(self.s.cert_dir, f'{fake_od_m.hex()}.key')))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.s.cert_dir, f'{fake_od_d.hex()}.key')))
Ejemplo n.º 5
0
 def setUp(self):
     self.ctx = zmq.asyncio.Context()
     self.loop = asyncio.new_event_loop()
     ContractingClient().flush()
     asyncio.set_event_loop(self.loop)
Ejemplo n.º 6
0
    def __init__(self,
                 socket_base,
                 ctx: zmq.asyncio.Context,
                 wallet,
                 constitution: dict,
                 bootnodes={},
                 blocks=storage.BlockStorage(),
                 driver=ContractDriver(),
                 debug=True,
                 store=False,
                 seed=None,
                 bypass_catchup=False,
                 node_type=None,
                 genesis_path=lamden.contracts.__path__[0],
                 reward_manager=rewards.RewardManager(),
                 nonces=storage.NonceStorage()):

        self.driver = driver
        self.nonces = nonces
        self.store = store

        self.seed = seed

        self.blocks = blocks
        self.event_writer = EventWriter()

        self.log = get_logger('Base')
        self.log.propagate = debug
        self.socket_base = socket_base
        self.wallet = wallet
        self.ctx = ctx

        self.genesis_path = genesis_path

        self.client = ContractingClient(driver=self.driver,
                                        submission_filename=genesis_path +
                                        '/submission.s.py')

        self.bootnodes = bootnodes
        self.constitution = constitution

        self.seed_genesis_contracts()

        self.socket_authenticator = authentication.SocketAuthenticator(
            bootnodes=self.bootnodes, ctx=self.ctx, client=self.client)

        self.upgrade_manager = upgrade.UpgradeManager(client=self.client,
                                                      wallet=self.wallet,
                                                      node_type=node_type)

        self.router = router.Router(socket_id=socket_base,
                                    ctx=self.ctx,
                                    wallet=wallet,
                                    secure=True)

        self.network = network.Network(wallet=wallet,
                                       ip_string=socket_base,
                                       ctx=self.ctx,
                                       router=self.router)

        self.new_block_processor = NewBlock(driver=self.driver)
        self.router.add_service(
            NEW_BLOCK_SERVICE,
            self.new_block_processor)  # Add this after catch up?

        self.running = False
        self.upgrade = False

        self.reward_manager = reward_manager

        self.current_height = storage.get_latest_block_height(self.driver)
        self.current_hash = storage.get_latest_block_hash(self.driver)

        self.bypass_catchup = bypass_catchup
Ejemplo n.º 7
0
from contracting.client import ContractingClient
client = ContractingClient()

# Make sure mongdob is running
# docker run -d -p 27017–27019:27017–27019 — name mongodb mongo:4.2


def hello_world():
    @export
    def hello():
        return 'World!'

    # @export must be typesafe
    @export
    def add(a: int, b: int):
        return private_add(a, b)

    # @private functions do not require to be typesafe
    def private_add(a, b):
        return a + b
Ejemplo n.º 8
0
def transaction_is_valid(transaction,
                         expected_processor,
                         client: ContractingClient,
                         nonces: storage.NonceStorage,
                         strict=True,
                         tx_per_block=15,
                         timeout=5):
    # Check basic formatting so we can access via __getitem__ notation without errors
    if not check_format(transaction, rules.TRANSACTION_RULES):
        return TransactionFormattingError

    transaction_is_not_expired(transaction, timeout)

    # Put in to variables for visual ease
    processor = transaction['payload']['processor']
    sender = transaction['payload']['sender']

    # Checks if correct processor and if signature is valid
    check_tx_formatting(transaction, expected_processor)

    # Gets the expected nonces
    nonce, pending_nonce = get_nonces(sender, processor, nonces)

    # Get the provided nonce
    tx_nonce = transaction['payload']['nonce']

    # Check to see if the provided nonce is valid to what we expect and
    # if there are less than the max pending txs in the block
    get_new_pending_nonce(tx_nonce,
                          nonce,
                          pending_nonce,
                          strict=strict,
                          tx_per_block=tx_per_block)

    # Get the senders balance and the current stamp rate
    balance = client.get_var(contract='currency',
                             variable='balances',
                             arguments=[sender],
                             mark=False)
    stamp_rate = client.get_var(contract='stamp_cost',
                                variable='S',
                                arguments=['value'],
                                mark=False)

    contract = transaction['payload']['contract']
    func = transaction['payload']['function']
    stamps_supplied = transaction['payload']['stamps_supplied']
    if stamps_supplied is None:
        stamps_supplied = 0

    if stamp_rate is None:
        stamp_rate = 0

    if balance is None:
        balance = 0

    # Get how much they are sending
    amount = transaction['payload']['kwargs'].get('amount')
    if amount is None:
        amount = 0

    # Check if they have enough stamps for the operation
    has_enough_stamps(balance,
                      stamp_rate,
                      stamps_supplied,
                      contract=contract,
                      function=func,
                      amount=amount)

    # Check if contract name is valid
    name = transaction['payload']['kwargs'].get('name')
    contract_name_is_valid(contract, func, name)
Ejemplo n.º 9
0
class TestDynamicImports(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

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

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

        self.c.raw_driver.commit()

        # submit erc20 clone
        with open('./test_contracts/stubucks.s.py') as f:
            code = f.read()
            self.c.submit(code, name='stubucks')

        with open('./test_contracts/tejastokens.s.py') as f:
            code = f.read()
            self.c.submit(code, name='tejastokens')

        with open('./test_contracts/bastardcoin.s.py') as f:
            code = f.read()
            self.c.submit(code, name='bastardcoin')

        with open('./test_contracts/dynamic_importing.s.py') as f:
            code = f.read()
            self.c.submit(code, name='dynamic_importing')

        self.stubucks = self.c.get_contract('stubucks')
        self.tejastokens = self.c.get_contract('tejastokens')
        self.bastardcoin = self.c.get_contract('bastardcoin')
        self.dynamic_importing = self.c.get_contract('dynamic_importing')

    def tearDown(self):
        self.c.raw_driver.flush()

    def test_successful_submission(self):
        self.assertEqual(self.stubucks.balance_of(account='stu'), 123)
        self.assertEqual(self.stubucks.balance_of(account='colin'), 321)

        self.assertEqual(self.tejastokens.balance_of(account='stu'), 321)
        self.assertEqual(self.tejastokens.balance_of(account='colin'), 123)

        self.assertEqual(self.bastardcoin.balance_of(account='stu'), 999)
        self.assertEqual(self.bastardcoin.balance_of(account='colin'), 555)

    def test_get_stubuck_balances(self):
        stu = self.dynamic_importing.balance_for_token(tok='stubucks',
                                                       account='stu')
        colin = self.dynamic_importing.balance_for_token(tok='stubucks',
                                                         account='colin')

        self.assertEqual(stu, 123)
        self.assertEqual(colin, 321)

    def test_get_tejastokens_balances(self):
        stu = self.dynamic_importing.balance_for_token(tok='tejastokens',
                                                       account='stu')
        colin = self.dynamic_importing.balance_for_token(tok='tejastokens',
                                                         account='colin')

        self.assertEqual(stu, 321)
        self.assertEqual(colin, 123)

    def test_get_bastardcoin_balances(self):
        stu = self.dynamic_importing.balance_for_token(tok='bastardcoin',
                                                       account='stu')
        colin = self.dynamic_importing.balance_for_token(tok='bastardcoin',
                                                         account='colin')

        self.assertEqual(stu, 999)
        self.assertEqual(colin, 555)

    def test_is_erc20(self):
        self.assertTrue(
            self.dynamic_importing.is_erc20_compatible(tok='stubucks'))
        self.assertTrue(
            self.dynamic_importing.is_erc20_compatible(tok='tejastokens'))
        self.assertFalse(
            self.dynamic_importing.is_erc20_compatible(tok='bastardcoin'))

    def test_get_balances_erc20_enforced_stubucks(self):
        stu = self.dynamic_importing.only_erc20(tok='stubucks', account='stu')
        colin = self.dynamic_importing.only_erc20(tok='stubucks',
                                                  account='colin')

        self.assertEqual(stu, 123)
        self.assertEqual(colin, 321)

    def test_get_balances_erc20_enforced_tejastokens(self):
        stu = self.dynamic_importing.only_erc20(tok='tejastokens',
                                                account='stu')
        colin = self.dynamic_importing.only_erc20(tok='tejastokens',
                                                  account='colin')

        self.assertEqual(stu, 321)
        self.assertEqual(colin, 123)

    def test_erc20_enforced_fails_for_bastardcoin(self):
        with self.assertRaises(AssertionError):
            stu = self.dynamic_importing.only_erc20(tok='bastardcoin',
                                                    account='stu')

    def test_owner_of_returns_default(self):
        with open('./test_contracts/owner_stuff.s.py') as f:
            code = f.read()
            self.c.submit(code, name='owner_stuff', owner='poo')

        owner_stuff = self.c.get_contract('owner_stuff')

        self.assertIsNone(owner_stuff.get_owner(s='stubucks', signer='poo'))
        self.assertEqual(owner_stuff.get_owner(s='owner_stuff', signer='poo'),
                         'poo')

    def test_ctx_owner_works(self):
        with open('./test_contracts/owner_stuff.s.py') as f:
            code = f.read()
            self.c.submit(code, name='owner_stuff', owner='poot')

        owner_stuff = self.c.get_contract('owner_stuff')

        self.assertEqual(owner_stuff.owner_of_this(signer='poot'), 'poot')

    def test_incorrect_owner_prevents_function_call(self):
        with open('./test_contracts/owner_stuff.s.py') as f:
            code = f.read()
            self.c.submit(code, name='owner_stuff', owner='poot')

        owner_stuff = self.c.get_contract('owner_stuff')
        with self.assertRaises(Exception):
            owner_stuff.owner_of_this()

    def test_delegate_call_with_owner_works(self):
        with open('./test_contracts/parent_test.s.py') as f:
            code = f.read()
            self.c.submit(code, name='parent_test')

        with open('./test_contracts/child_test.s.py') as f:
            code = f.read()
            self.c.submit(code, name='child_test', owner='parent_test')

        parent_test = self.c.get_contract('parent_test')

        val = parent_test.get_val_from_child(s='child_test')

        self.assertEqual(val, 'good')

    def test_delegate_with_wrong_owner_does_not_work(self):
        with open('./test_contracts/parent_test.s.py') as f:
            code = f.read()
            self.c.submit(code, name='parent_test')

        with open('./test_contracts/child_test.s.py') as f:
            code = f.read()
            self.c.submit(code, name='child_test', owner='blorg')

        parent_test = self.c.get_contract('parent_test')

        with self.assertRaises(Exception) as e:
            parent_test.get_val_from_child(s='child_test')
Ejemplo n.º 10
0
class TestDeveloperSubmission(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

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

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

        self.c.raw_driver.commit()

    def test_submit_sets_developer(self):
        self.c.submit(test)

        dev = self.c.get_var('test', '__developer__')

        self.assertEqual(dev, 'stu')

    def test_change_developer_if_developer_works(self):
        self.c.submit(test)

        submission = self.c.get_contract('submission')

        submission.change_developer(contract='test', new_developer='not_stu')

        dev = self.c.get_var('test', '__developer__')

        self.assertEqual(dev, 'not_stu')

    def test_change_developer_prevents_new_change(self):
        self.c.submit(test)

        submission = self.c.get_contract('submission')

        submission.change_developer(contract='test', new_developer='not_stu')

        with self.assertRaises(AssertionError):
            submission.change_developer(contract='test', new_developer='woohoo')

    def test_cannot_import_submission(self):
        self.c.submit(import_submission)

        imp_con = self.c.get_contract('import_submission')

        with self.assertRaises(AssertionError):
            imp_con.haha()
Ejemplo n.º 11
0
class TestMiscContracts(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

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

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

        self.c.raw_driver.commit()

        submission = self.c.get_contract('submission')

        self.c.submit(too_many_writes)

        # submit erc20 clone
        with open('./test_contracts/thing.s.py') as f:
            code = f.read()
            self.c.submit(code, name='thing')

        with open('./test_contracts/foreign_thing.s.py') as f:
            code = f.read()
            self.c.submit(code, name='foreign_thing')

        self.thing = self.c.get_contract('thing')
        self.foreign_thing = self.c.get_contract('foreign_thing')

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

    def test_H_values_return(self):
        output = self.foreign_thing.read_H_hello()
        self.assertEqual(output, 'there')

        output = self.foreign_thing.read_H_something()
        self.assertEqual(output, 'else')

    def test_cant_modify_H(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_H(k='hello', v='not_there')

    def test_cant_add_H(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_H(k='asdf', v='123')

    def test_cant_set_V(self):
        with self.assertRaises(ReferenceError):
            self.foreign_thing.set_V(v=123)

    def test_V_returns(self):
        output = self.foreign_thing.read_V()
        self.assertEqual(output, 'hi')

    def test_single_too_many_writes_fails(self):
        tmwc = self.c.get_contract('too_many_writes')
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            tmwc.single()
        self.c.executor.metering = False

    def test_multiple_too_many_writes_fails(self):
        tmwc = self.c.get_contract('too_many_writes')
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            tmwc.multiple()
        self.c.executor.metering = False

    def test_failed_once_doesnt_affect_others(self):
        tmwc = self.c.get_contract('too_many_writes')
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            tmwc.multiple()
        tmwc.not_enough()
        self.c.executor.metering = False

    def test_memory_overload(self):
        tmwc = self.c.get_contract('too_many_writes')
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            tmwc.run()
        self.c.executor.metering = False

    def test_memory_overload2(self):
        tmwc = self.c.get_contract('too_many_writes')
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            tmwc.run2()
        self.c.executor.metering = False

    def test_memory_exploit(self):
        self.c.executor.metering = True
        self.c.set_var(contract='currency', variable='balances', arguments=['stu'], value=1000000)
        with self.assertRaises(AssertionError):
            self.c.submit(exploit)
        self.c.executor.metering = False
Ejemplo n.º 12
0
class TestSenecaClientReplacesExecutor(TestCase):
    def setUp(self):
        self.c = ContractingClient(signer='stu')
        self.c.raw_driver.flush()

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

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

        self.c.raw_driver.commit()

        submission = self.c.get_contract('submission')

        # submit erc20 clone
        with open('./test_contracts/erc20_clone.s.py') as f:
            code = f.read()
            self.c.submit(code, name='erc20_clone')

        with open('./test_contracts/atomic_swaps.s.py') as f:
            code = f.read()
            self.c.submit(code, name='atomic_swaps')

        self.erc20_clone = self.c.get_contract('erc20_clone')
        self.atomic_swaps = self.c.get_contract('atomic_swaps')

    def tearDown(self):
        self.c.raw_driver.flush()

    def test_initiate_not_enough_approved(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        with self.assertRaises(AssertionError):
            self.atomic_swaps.initiate(
                participant='raghu',
                expiration=Datetime(2020, 1, 1),
                hashlock=
                'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
                amount=5000000)

    def test_initiate_transfers_coins_correctly(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        atomic_swaps = self.erc20_clone.balance_of(account='atomic_swaps')
        stu_bal = self.erc20_clone.balance_of(account='stu')
        stu_as = self.erc20_clone.allowance(owner='stu',
                                            spender='atomic_swaps')

        self.assertEqual(atomic_swaps, 5)
        self.assertEqual(stu_bal, 999995)
        self.assertEqual(stu_as, 999995)

    def test_initiate_writes_to_correct_key_and_properly(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        key = 'atomic_swaps.swaps:raghu:eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514'

        expiration, amount = self.c.raw_driver.get(key)
        self.assertEqual(expiration, Datetime(2020, 1, 1))
        self.assertEqual(amount, 5)

    def test_redeem_on_wrong_secret_fails(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        with self.assertRaises(AssertionError):
            self.atomic_swaps.redeem(signer='raghu', secret='00')

    def test_redeem_on_wrong_sender_fails(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')
        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        with self.assertRaises(AssertionError):
            self.atomic_swaps.redeem(secret='842b65a7d48e3a3c3f0e9d37eaced0b2')

    def test_past_expiration_fails(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2021, 1, 1)}

        with self.assertRaises(AssertionError):
            self.atomic_swaps.redeem(secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                     signer='raghu',
                                     environment=environment)

    def test_successful_redeem_transfers_coins_correctly(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2019, 1, 1)}

        self.atomic_swaps.redeem(secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                 signer='raghu',
                                 environment=environment)

        atomic_swaps = self.erc20_clone.balance_of(account='atomic_swaps')
        raghu = self.erc20_clone.balance_of(account='raghu')

        self.assertEqual(raghu, 5)
        self.assertEqual(atomic_swaps, 0)

    def test_successful_redeem_deletes_entry(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2019, 1, 1)}

        self.atomic_swaps.redeem(secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                 signer='raghu',
                                 environment=environment)

        key = 'atomic_swaps.swaps:raghu:eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514'
        v = self.c.raw_driver.get(key)

        self.assertEqual(v, None)

    def test_refund_works(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2021, 1, 1)}

        self.atomic_swaps.refund(participant='raghu',
                                 secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                 environment=environment)

        atomic_swaps = self.erc20_clone.balance_of(account='atomic_swaps')
        stu = self.erc20_clone.balance_of(account='stu')

        self.assertEqual(stu, 1000000)
        self.assertEqual(atomic_swaps, 0)

    def test_refund_too_early_fails(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2019, 1, 1)}

        with self.assertRaises(AssertionError):
            self.atomic_swaps.refund(participant='raghu',
                                     secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                     environment=environment)

    def test_refund_participant_is_signer_fails(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2021, 1, 1)}

        with self.assertRaises(AssertionError):
            self.atomic_swaps.refund(participant='raghu',
                                     secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                     environment=environment,
                                     signer='raghu')

    def test_refund_fails_with_wrong_secret(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2021, 1, 1)}

        with self.assertRaises(AssertionError):
            self.atomic_swaps.refund(
                participant='raghu',
                secret='00',
                environment=environment,
            )

    def test_refund_resets_swaps(self):
        self.erc20_clone.approve(amount=1000000, to='atomic_swaps')

        self.atomic_swaps.initiate(
            participant='raghu',
            expiration=Datetime(2020, 1, 1),
            hashlock=
            'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            amount=5)

        environment = {'now': Datetime(2021, 1, 1)}

        self.atomic_swaps.refund(participant='raghu',
                                 secret='842b65a7d48e3a3c3f0e9d37eaced0b2',
                                 environment=environment)

        key = 'atomic_swaps.swaps:raghu:eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514'
        v = self.c.raw_driver.get(key)

        self.assertEqual(v, None)
Ejemplo n.º 13
0
class TokenTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        with open('dai.py') as file:
            code = file.read()
        self.client.submit(code,
                           name='dai_token',
                           constructor_args={'owner': 'me'})
        self.dai = self.client.get_contract('dai_token')

        self.dai.mint(amount=1000000, signer='me')

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

    def test_transfer_negative(self):
        try:
            self.dai.transfer(amount=-1, to='wallet2', signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_transfer_excess(self):
        try:
            self.dai.transfer(amount=1000001, to='wallet2', signer='me')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_transfer_normal(self):
        self.dai.transfer(amount=42, to='wallet2', signer='me')
        self.assertAlmostEqual(self.dai.balance_of(account='me'), 1000000 - 42)
        self.assertAlmostEqual(self.dai.balance_of(account='wallet2'), 42)

    def test_balance(self):
        self.assertAlmostEqual(self.dai.balance_of(account='me'), 1000000)
        self.assertAlmostEqual(self.dai.balance_of(account='wallet2'), 0)

    def test_accounts_negative(self):
        try:
            self.dai.approve(amount=-1, to='account1', signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_accounts_normal(self):
        self.dai.approve(amount=42, to='account1', signer='me')
        self.assertAlmostEqual(
            self.dai.allowance(owner='me', spender='account1', signer='me'),
            42)

    def test_transfer_from_negative(self):
        self.dai.approve(amount=42, to='account1', signer='me')
        try:
            self.dai.transfer_from(amount=-1,
                                   to='wallet2',
                                   main_account='me',
                                   signer='account1')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_transfer_from_excess(self):
        self.dai.approve(amount=42, to='account1', signer='me')
        try:
            self.dai.transfer_from(amount=1000001,
                                   to='wallet2',
                                   main_account='me',
                                   signer='account1')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_transfer_from_approved(self):
        self.dai.approve(amount=42, to='account1', signer='me')
        try:
            self.dai.transfer_from(amount=1000000,
                                   to='wallet2',
                                   main_account='me',
                                   signer='account1')
            raise
        except AssertionError as message:
            assert 'approved' in str(message)

    def test_transfer_from_normal(self):
        self.dai.approve(amount=42, to='account1', signer='me')
        self.dai.transfer_from(amount=42,
                               to='wallet2',
                               main_account='me',
                               signer='account1')
        self.assertAlmostEqual(
            self.dai.allowance(owner='me', spender='account1', signer='me'), 0)
        self.assertAlmostEqual(self.dai.balance_of(account='me'), 1000000 - 42)
        self.assertAlmostEqual(self.dai.balance_of(account='wallet2'), 42)

    def test_burn_negative(self):
        try:
            self.dai.burn(amount=-1, signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_burn_excess(self):
        try:
            self.dai.burn(amount=1000001, signer='me')
            raise
        except AssertionError as message:
            assert 'enough' in str(message)

    def test_burn_normal(self):
        old_supply = self.dai.get_total_supply()
        self.dai.burn(amount=42, signer='me')
        self.assertAlmostEqual(self.dai.get_total_supply(), old_supply - 42)

    def test_mint_negative(self):
        try:
            self.dai.mint(amount=-1, signer='me')
            raise
        except AssertionError as message:
            assert 'negative' in str(message)

    def test_mint_unauthorised(self):
        try:
            self.dai.mint(amount=42, signer='wallet1')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_mint_normal(self):
        old_supply = self.dai.get_total_supply()
        self.dai.mint(amount=42, signer='me')
        self.assertAlmostEqual(self.dai.get_total_supply(), old_supply + 42)

    def test_metadata_unauthorised(self):
        try:
            self.dai.change_metadata(key='testing',
                                     value='testing',
                                     signer='me')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_metadata_normal(self):
        self.dai.change_metadata(key='testing', value='testing')
        assert self.dai.metadata['testing'] == 'testing'
        self.dai.change_metadata(key='testing', value='again')
        assert self.dai.metadata['testing'] == 'again'

    def test_change_owner_unauthorised(self):
        try:
            self.dai.change_owner(new_owner='wallet2', signer='wallet2')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)

    def test_change_owner_normal(self):
        self.dai.change_owner(new_owner='wallet2', signer='me')
        try:
            self.dai.change_owner(new_owner='me', signer='me')
            raise
        except AssertionError as message:
            assert 'operator' in str(message)
Ejemplo n.º 14
0
class StakingTests(unittest.TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        with open('tad.py') as file:
            tad = file.read()
        with open('vault.py') as file:
            vault = file.read()
        with open('test_currency.py') as file:
            currency = file.read()
        with open('oracle.py') as file:
            oracle = file.read()
        with open('stake.py') as file:
            staking = file.read()

        self.client.submit(tad,
                           name='tad_contract',
                           constructor_args={'owner': 'vault_contract'})
        self.client.submit(vault, name='vault_contract')
        self.client.submit(currency, name='currency')
        self.client.submit(oracle, name='oracle')
        self.client.submit(staking, name='staking')

        self.tad = self.client.get_contract('tad_contract')
        self.vault = self.client.get_contract('vault_contract')
        self.currency = self.client.get_contract('currency')
        self.oracle = self.client.get_contract('oracle')
        self.staking = self.client.get_contract('staking')
        self.tad.mint(amount=2000000, signer='vault_contract')
        self.tad.transfer(amount=2000000,
                          to='testing_user',
                          signer='vault_contract')

        self.oracle.set_price(number=0, new_price=1.0)  # Probably not needed
        self.vault.change_any_state(key=('mint', 'DSR', 'owner'),
                                    new_value='staking')

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

    def test_metadata_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'operator'):
            self.staking.change_metadata(key='testing',
                                         value='testing',
                                         signer='me')

    def test_metadata_normal(self):
        self.staking.change_metadata(key='testing', value='testing')
        assert self.staking.metadata['testing'] == 'testing'
        self.staking.change_metadata(key='testing', value='again')
        assert self.staking.metadata['testing'] == 'again'

    def test_change_owner_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'operator'):
            self.staking.change_owner(new_owner='wallet2', signer='wallet2')

    def test_change_owner_normal(self):
        self.staking.change_owner(new_owner='wallet2')
        with self.assertRaisesRegex(AssertionError, 'operator'):
            self.staking.change_owner(new_owner='me')
        self.staking.change_owner(new_owner='me', signer='wallet2')

    def test_change_rate_unauthorised(self):
        with self.assertRaisesRegex(AssertionError, 'operator'):
            self.staking.change_rate(new_rate=0.1, signer='wallet2')

    def test_change_rate_negative(self):
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.staking.change_rate(new_rate=-0.1)

    def test_change_rate_normal(self):
        current_price = self.staking.get_price()
        self.staking.change_rate(new_rate=0.1)

        self.assertAlmostEqual(0.1, self.staking.rate['rate'])
        self.assertAlmostEqual(self.staking.rate['start_price'], current_price)

    def test_stake_negative(self):
        with self.assertRaisesRegex(AssertionError, 'positive'):
            self.staking.stake(amount=-1)

    def test_stake_insufficient(self):
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.staking.stake(amount=1000001)

    def test_stake_normal(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')

    def test_stake_takes_money(self):
        self.assertAlmostEqual(self.tad.balance_of(account='testing_user'),
                               2000000)
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.assertAlmostEqual(self.tad.balance_of(account='testing_user'),
                               1000000)

    def test_stake_updates_balance(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.assertAlmostEqual(self.staking.balances['testing_user'], 1000000)

    def test_stake_sets_total_minted(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.assertAlmostEqual(self.staking.total_minted.get(), 2000000)

    def test_withdraw_stake_negative(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        with self.assertRaisesRegex(AssertionError, 'positive'):
            self.staking.withdraw_stake(amount=-1, signer='testing_user')

    def test_withdraw_stake_insufficient(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.staking.withdraw_stake(amount=1000001, signer='testing_user')

    def test_stake_records_balance(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.assertAlmostEqual(self.staking.balances['testing_user'], 1000000)
        self.assertEqual(self.staking.balances['wallet2'], None)

    def test_withdraw_stake_normal(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.withdraw_stake(amount=1000000, signer='testing_user')

    def test_withdraw_stake_returns_money(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.withdraw_stake(amount=1000000, signer='testing_user')
        self.assertAlmostEqual(self.tad.balance_of(account='testing_user'),
                               2000000)

    def test_withdraw_stake_returns_rewards(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        self.staking.withdraw_stake(amount=1000000,
                                    signer='testing_user',
                                    environment=env)
        assert self.tad.balance_of(account='testing_user') > 2000000

    def test_transfer_negative(self):
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.staking.transfer(amount=-1,
                                  to='wallet2',
                                  signer='testing_user')

    def test_transfer_excess(self):
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.staking.transfer(amount=1000001,
                                  to='wallet2',
                                  signer='testing_user')

    def test_transfer_normal(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.transfer(amount=42, to='wallet2', signer='testing_user')
        self.assertAlmostEqual(self.staking.balance_of(account='testing_user'),
                               1000000 - 42)
        self.assertAlmostEqual(self.staking.balance_of(account='wallet2'), 42)

    def test_accounts_negative(self):
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.staking.approve(amount=-1,
                                 to='account1',
                                 signer='testing_user')

    def test_accounts_excess(self):
        with self.assertRaisesRegex(AssertionError, 'exceeds'):
            self.staking.approve(amount=1000001,
                                 to='account1',
                                 signer='testing_user')

    def test_accounts_updates_internal_balance(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        self.assertAlmostEqual(
            self.staking.balances['testing_user', 'account1'], 42)

    def test_accounts_normal(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        self.assertAlmostEqual(
            self.staking.allowance(owner='testing_user',
                                   spender='account1',
                                   signer='me'), 42)

    def test_transfer_from_negative(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        with self.assertRaisesRegex(AssertionError, 'negative'):
            self.staking.transfer_from(amount=-1,
                                       to='wallet2',
                                       main_account='testing_user',
                                       signer='account1')

    def test_transfer_from_excess(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        with self.assertRaisesRegex(AssertionError, 'enough'):
            self.staking.transfer_from(amount=1000001,
                                       to='wallet2',
                                       main_account='testing_user',
                                       signer='account1')

    def test_transfer_from_approved(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        with self.assertRaisesRegex(AssertionError, 'approved'):
            self.staking.transfer_from(amount=1000000,
                                       to='wallet2',
                                       main_account='testing_user',
                                       signer='account1')

    def test_transfer_from_normal_sends(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        self.staking.transfer_from(amount=42,
                                   to='wallet2',
                                   main_account='testing_user',
                                   signer='account1')
        self.assertAlmostEqual(
            self.staking.allowance(owner='testing_user',
                                   spender='account1',
                                   signer='me'), 0)
        self.assertAlmostEqual(self.staking.balance_of(account='testing_user'),
                               1000000 - 42)

    def test_transfer_from_normal_receives(self):
        self.tad.approve(to='staking', amount=1000000, signer='testing_user')
        self.staking.stake(amount=1000000, signer='testing_user')
        self.staking.approve(amount=42, to='account1', signer='testing_user')
        self.staking.transfer_from(amount=42,
                                   to='wallet2',
                                   main_account='testing_user',
                                   signer='account1')
        self.assertAlmostEqual(self.staking.balance_of(account='wallet2'), 42)

    def test_get_price(self):
        current_rate = self.staking.get_price()
        env = {'now': Datetime(year=2022, month=12, day=31)}  # mocks the date
        with self.assertRaisesRegex(AssertionError, '!='):
            self.assertEqual(current_rate,
                             self.staking.get_price(environment=env))

    def test_timestamp_is_correct(self):
        assert abs(datetime.datetime.utcnow().timestamp() -
                   self.vault.get_timestamp()) % 14400 < 120
Ejemplo n.º 15
0
#tests/test_contract.py
import unittest

from contracting.client import ContractingClient
client = ContractingClient()

with open('../my_token.py') as f:
    code = f.read()
    client.submit(code, name='my_token')


class MyTestCase(unittest.TestCase):
    def test_supply(self):
        # Get contract reference
        my_token = client.get_contract('my_token')
        # Assert token balance for 'me'
        self.assertEqual(my_token.quick_read('S', 'me'), 50)

    def test_transfer(self):
        # set transaction sender
        client.signer = 'me'
        # Get contract reference
        my_token = client.get_contract('my_token')
        # Call transfer method
        my_token.transfer(amount=10, receiver='you')
        # Assert token balance for 'me'
        self.assertEqual(my_token.quick_read('S', 'me'), 40)
        # Assert token balance for 'you'
        self.assertEqual(my_token.quick_read('S', 'you'), 10)

    def test_transfer_neg_insufficient_funds(self):
Ejemplo n.º 16
0
import unittest
from contracting.client import ContractingClient

# make sure mongoDB is running with: sudo systemctl start mongod
client = ContractingClient()

filelocation = '/home/covenant/Documents/Lamden/Automated Pay Distribution/apd_v01.py'  #main_file.py'
filename = 'apd'  #'main_file'

with open(filelocation) as f:
    code = f.read()
    client.submit(code,
                  name=filename,
                  constructor_args={
                      'vk': 'me',
                      'amount': 50
                  })


class MyTestCase(unittest.TestCase):
    def test_supply(self):
        contract = client.get_contract(filename)
        supply = 50
        #print(contract.quick_read('State', 'me'), supply)

        self.assertEqual(contract.quick_read('State', 'me'), supply)

    def test_transfer(self):
        client.signer = 'me'
        contract = client.get_contract(filename)
        supply = 50
Ejemplo n.º 17
0
class Node:
    def __init__(self,
                 socket_base,
                 ctx: zmq.asyncio.Context,
                 wallet,
                 constitution: dict,
                 bootnodes={},
                 blocks=storage.BlockStorage(),
                 driver=ContractDriver(),
                 debug=True,
                 store=False,
                 seed=None,
                 bypass_catchup=False,
                 node_type=None,
                 genesis_path=lamden.contracts.__path__[0],
                 reward_manager=rewards.RewardManager(),
                 nonces=storage.NonceStorage()):

        self.driver = driver
        self.nonces = nonces
        self.store = store

        self.seed = seed

        self.blocks = blocks
        self.event_writer = EventWriter()

        self.log = get_logger('Base')
        self.log.propagate = debug
        self.socket_base = socket_base
        self.wallet = wallet
        self.ctx = ctx

        self.genesis_path = genesis_path

        self.client = ContractingClient(driver=self.driver,
                                        submission_filename=genesis_path +
                                        '/submission.s.py')

        self.bootnodes = bootnodes
        self.constitution = constitution

        self.seed_genesis_contracts()

        self.socket_authenticator = authentication.SocketAuthenticator(
            bootnodes=self.bootnodes, ctx=self.ctx, client=self.client)

        self.upgrade_manager = upgrade.UpgradeManager(client=self.client,
                                                      wallet=self.wallet,
                                                      node_type=node_type)

        self.router = router.Router(socket_id=socket_base,
                                    ctx=self.ctx,
                                    wallet=wallet,
                                    secure=True)

        self.network = network.Network(wallet=wallet,
                                       ip_string=socket_base,
                                       ctx=self.ctx,
                                       router=self.router)

        self.new_block_processor = NewBlock(driver=self.driver)
        self.router.add_service(
            NEW_BLOCK_SERVICE,
            self.new_block_processor)  # Add this after catch up?

        self.running = False
        self.upgrade = False

        self.reward_manager = reward_manager

        self.current_height = storage.get_latest_block_height(self.driver)
        self.current_hash = storage.get_latest_block_hash(self.driver)

        self.bypass_catchup = bypass_catchup

    def seed_genesis_contracts(self):
        self.log.info('Setting up genesis contracts.')
        sync.setup_genesis_contracts(
            initial_masternodes=self.constitution['masternodes'],
            initial_delegates=self.constitution['delegates'],
            client=self.client,
            filename=self.genesis_path + '/genesis.json',
            root=self.genesis_path)

    async def catchup(self, mn_seed, mn_vk):
        # Get the current latest block stored and the latest block of the network
        self.log.info('Running catchup.')
        current = self.current_height
        latest = await get_latest_block_height(ip=mn_seed,
                                               vk=mn_vk,
                                               wallet=self.wallet,
                                               ctx=self.ctx)

        self.log.info(
            f'Current block: {current}, Latest available block: {latest}')

        if latest == 0 or latest is None or type(latest) == dict:
            self.log.info('No need to catchup. Proceeding.')
            return

        # Increment current by one. Don't count the genesis block.
        if current == 0:
            current = 1

        # Find the missing blocks process them
        for i in range(current, latest + 1):
            block = None
            while block is None:
                block = await get_block(block_num=i,
                                        ip=mn_seed,
                                        vk=mn_vk,
                                        wallet=self.wallet,
                                        ctx=self.ctx)
            self.process_new_block(block)

        # Process any blocks that were made while we were catching up
        while len(self.new_block_processor.q) > 0:
            block = self.new_block_processor.q.pop(0)
            self.process_new_block(block)

    def should_process(self, block):
        try:
            self.log.info(f'Processing block #{block.get("number")}')
        except:
            self.log.error('Malformed block :(')
            return False
        # Test if block failed immediately
        if block == {'response': 'ok'}:
            return False

        if block['hash'] == 'f' * 64:
            self.log.error('Failed Block! Not storing.')
            return False

        # Get current metastate
        # if len(block['subblocks']) < 1:
        #    return False

        # Test if block contains the same metastate
        # if block['number'] != self.current_height + 1:
        #     self.log.info(f'Block #{block["number"]} != {self.current_height + 1}. '
        #                   f'Node has probably already processed this block. Continuing.')
        #     return False

        # if block['previous'] != self.current_hash:
        #     self.log.error('Previous block hash != Current hash. Cryptographically invalid. Not storing.')
        #     return False

        # If so, use metastate and subblocks to create the 'expected' block
        # expected_block = canonical.block_from_subblocks(
        #     subblocks=block['subblocks'],
        #     previous_hash=self.current_hash,
        #     block_num=self.current_height + 1
        # )

        # Return if the block contains the expected information
        # good = block == expected_block
        # if good:
        #     self.log.info(f'Block #{block["number"]} passed all checks. Store.')
        # else:
        #     self.log.error(f'Block #{block["number"]} has an encoding problem. Do not store.')
        #
        # return good

        return True

    def update_state(self, block):
        self.driver.clear_pending_state()

        # Check if the block is valid
        if self.should_process(block):
            self.log.info('Storing new block.')
            # Commit the state changes and nonces to the database
            storage.update_state_with_block(block=block,
                                            driver=self.driver,
                                            nonces=self.nonces)

            self.log.info('Issuing rewards.')
            # Calculate and issue the rewards for the governance nodes
            self.reward_manager.issue_rewards(block=block, client=self.client)

        #self.nonces.flush_pending()

        self.log.info('Updating metadata.')
        self.current_height = storage.get_latest_block_height(self.driver)
        self.current_hash = storage.get_latest_block_hash(self.driver)

        self.new_block_processor.clean(self.current_height)

    def process_new_block(self, block):
        # Update the state and refresh the sockets so new nodes can join
        self.update_state(block)
        self.socket_authenticator.refresh_governance_sockets()

        # Store the block if it's a masternode
        if self.store:
            encoded_block = encode(block)
            encoded_block = json.loads(encoded_block)

            self.blocks.store_block(encoded_block)

            # create Event File
            self.event_writer.write_event(
                Event(topics=[NEW_BLOCK_EVENT], data=encoded_block))

        # Prepare for the next block by flushing out driver and notification state
        # self.new_block_processor.clean()

        # Finally, check and initiate an upgrade if one needs to be done
        self.driver.commit()

        self.driver.clear_pending_state()
        gc.collect()  # Force memory cleanup every block

        self.nonces.flush_pending()

    async def start(self):
        asyncio.ensure_future(self.router.serve())

        # Get the set of VKs we are looking for from the constitution argument
        vks = self.constitution['masternodes'] + self.constitution['delegates']

        for node in self.bootnodes.keys():
            self.socket_authenticator.add_verifying_key(node)

        self.socket_authenticator.configure()

        # Use it to boot up the network
        await self.network.start(bootnodes=self.bootnodes, vks=vks)

        if not self.bypass_catchup:
            masternode_ip = None
            masternode = None

            if self.seed is not None:
                for k, v in self.bootnodes.items():
                    self.log.info(k, v)
                    if v == self.seed:
                        masternode = k
                        masternode_ip = v
            else:
                masternode = self.constitution['masternodes'][0]
                masternode_ip = self.network.peers[masternode]

            self.log.info(f'Masternode Seed VK: {masternode}')

            # Use this IP to request any missed blocks
            await self.catchup(mn_seed=masternode_ip, mn_vk=masternode)

        # Refresh the sockets to accept new nodes
        self.socket_authenticator.refresh_governance_sockets()

        # Start running
        self.running = True

    def stop(self):
        # Kill the router and throw the running flag to stop the loop
        self.router.stop()
        self.running = False

    def _get_member_peers(self, contract_name):
        members = self.client.get_var(contract=contract_name,
                                      variable='S',
                                      arguments=['members'])

        member_peers = dict()

        for member in members:
            ip = self.network.peers.get(member)
            if ip is not None:
                member_peers[member] = ip

        return member_peers

    def get_delegate_peers(self):
        return self._get_member_peers('delegates')

    def get_masternode_peers(self):
        return self._get_member_peers('masternodes')

    def make_constitution(self):
        return {
            'masternodes': self.get_masternode_peers(),
            'delegates': self.get_delegate_peers()
        }
Ejemplo n.º 18
0
#tests/test_contract.py
import unittest
import base64
from contracting.client import ContractingClient
client = ContractingClient()

initial_args = {
    'owner': 'stu_man',
    'wait_period_hours': 0,
    'max_send': 2,
    'drip': 1,
    'currency_symbol': 'jTAU'
}

new_args = {
    'owner': 'jeff_man',
    'wait_period_hours': 1,
    'max_send': 100,
    'drip': 100,
    'currency_symbol': 'dTAU'
}

icon_svg_base64 = ""

with open('./currency.py') as f:
    code = f.read()
    client.submit(code, name='currency')
with open('../contracts/con_faucet.py') as f:
    code = f.read()
    client.submit(code, name='con_faucet', constructor_args=initial_args)
Ejemplo n.º 19
0
class DexPairsSpecs(TestCase):

    # returns ContractingDecimal
    def expand_to_token_decimals(self, amount):
        return ContractingDecimal(amount / pow(10, TOKEN_DECIMALS))

    # before each test, setup the conditions
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        self.fee_to_address = 'fee_to_address'
        self.fee_to_setter_address = 'fee_to_setter_address'
        self.wallet_address = 'wallet_address'

        # token0
        with open('../currency.py') as f:
            code = f.read()
            self.client.submit(code,
                               'tau',
                               constructor_args={
                                   's_name': 'tau',
                                   's_symbol': 'TAU',
                                   'vk': self.wallet_address,
                                   'vk_amount': 10000
                               })

        # token1
        with open('../basetoken.py') as f:
            code = f.read()
            self.client.submit(code,
                               name='eth',
                               constructor_args={
                                   's_name': 'eth',
                                   's_symbol': 'ETH',
                                   'vk': self.wallet_address,
                                   'vk_amount': 10000
                               })

        # Dex
        with open('../dex.py') as f:
            code = f.read()
            self.client.submit(code,
                               'dex',
                               constructor_args={
                                   'fee_to_setter_address':
                                   self.fee_to_setter_address
                               })

        # Dex Pairs
        # Initialize ownership to dex
        with open('../dex_pairs.py') as f:
            code = f.read()
            self.client.submit(code,
                               'dex_pairs',
                               constructor_args={'owner_address': 'dex'})

        # Change tx signer to actor1
        self.change_signer(self.wallet_address)

        # Create pair on Dex
        self.dex.create_pair(dex_pairs='dex_pairs',
                             tau_contract='tau',
                             token_contract='eth')

    def change_signer(self, name):
        self.client.signer = name

        self.tau = self.client.get_contract('tau')
        self.eth = self.client.get_contract('eth')
        self.dex = self.client.get_contract('dex')
        self.dex_pairs = self.client.get_contract('dex_pairs')

    def zero_address(self):
        return '0'

    def test_1_mint(self):
        self.change_signer(self.wallet_address)

        tau_amount = 1.0
        eth_amount = 4.0

        self.tau.transfer(amount=tau_amount, to=self.dex_pairs.name)
        self.eth.transfer(amount=eth_amount, to=self.dex_pairs.name)

        expected_liquidity = 2.0
        token_mint_address, tau_amount, token_amount = self.dex_pairs.mint_liquidity(
            dex_contract=self.dex.name,
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            to_address=self.wallet_address)

        # TODO - A4 - Asserts on Emit()
        total_supply = self.dex_pairs.total_supply(
            tau_contract=self.tau.name, token_contract=self.eth.name)
        assert total_supply == expected_liquidity, 'Invalid Total supply'

        zero_address_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.zero_address())
        assert zero_address_balance == self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY), 'Invalid minimum liquidity initialized'

        wallet_address_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.wallet_address)
        assert wallet_address_balance == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY), 'Invalid balance initialized'

        assert self.tau.balance_of(
            account=self.dex_pairs.name) == tau_amount, 'Invalid tau balance'
        assert self.eth.balance_of(account=self.dex_pairs.name
                                   ) == eth_amount, 'Invalid ethereum balance'

        tau_reserves, token_reserves = self.dex_pairs.get_pair_reserves(
            tau_contract=self.tau.name, token_contract=self.eth.name)

        assert tau_reserves == tau_amount, 'Invalid tau reserves'
        assert token_reserves == eth_amount, 'Invalid eth reserves'

    def add_liquidity(self, tau_amount, token_amount):
        self.tau.transfer(amount=tau_amount, to=self.dex_pairs.name)
        self.eth.transfer(amount=token_amount, to=self.dex_pairs.name)

        self.dex_pairs.mint_liquidity(dex_contract=self.dex.name,
                                      tau_contract=self.tau.name,
                                      token_contract=self.eth.name,
                                      to_address=self.wallet_address)

    def test_2_0_swap_tests(self):
        swap_test_cases = [[1, 5, 10, '1662497915624478906'],
                           [1, 10, 5, '453305446940074565'],
                           [2, 5, 10, '2851015155847869602'],
                           [2, 10, 5, '831248957812239453'],
                           [1, 10, 10, '906610893880149131'],
                           [1, 100, 100, '987158034397061298'],
                           [1, 1000, 1000, '996006981039903216']]

        swap_test_cases = map(
            lambda case: map(
                lambda x: self.expand_to_token_decimals(int(x))
                if isinstance(x, str) else ContractingDecimal(int(x)), case),
            swap_test_cases)

        index = 0
        for test_case in swap_test_cases:
            self.setUp()

            swap_amount, tau_amount, token_amount, expected_output_amount = test_case

            index += 1
            print("Test Case [#{}] with params: [{},{},{},{}]".format(
                index, swap_amount, tau_amount, token_amount,
                expected_output_amount))

            self.add_liquidity(tau_amount, token_amount)
            self.tau.transfer(amount=swap_amount, to=self.dex_pairs.name)

            # TODO - A2 - Complete UniswapV2: K exceptions
            # with self.assertRaises(Exception) as context:
            # self.dex_pairs.swap(
            #     tau_contract=self.tau.name,
            #     token_contract=self.eth.name,
            #     tau_out=0,
            #     token_out=expected_output_amount + 1.0, # swap more
            #     to_address=self.wallet_address
            # )
            # self.assertTrue('UniswapV2: K' in context.exception, 'UniswapV2 ')

            self.dex_pairs.swap(tau_contract=self.tau.name,
                                token_contract=self.eth.name,
                                tau_out=0,
                                token_out=expected_output_amount,
                                to_address='test_results_wallet')

            # Validate Reserves
            tau_reserve, token_reserve = self.dex_pairs.get_pair_reserves(
                tau_contract=self.tau.name, token_contract=self.eth.name)

            self.assertEqual(tau_reserve, tau_amount + swap_amount)
            self.assertEqual(token_reserve,
                             token_amount - expected_output_amount)

            wallet_balance_tau = self.tau.balance_of(
                account='test_results_wallet')
            wallet_balance_token = self.eth.balance_of(
                account='test_results_wallet')
            self.assertEqual(wallet_balance_tau, 0)
            self.assertEqual(wallet_balance_token, expected_output_amount)

    def test_3_token0_swap(self):
        self.change_signer(self.wallet_address)

        tau_amount = 5
        token_amount = 10

        self.add_liquidity(tau_amount, token_amount)

        swap_amount = 1
        expected_output_amount = self.expand_to_token_decimals(
            1662497915624478906)

        self.tau.transfer(amount=swap_amount, to=self.dex_pairs.name)

        # TODO - A4 - Asserts on Emit()
        self.dex_pairs.swap(tau_contract=self.tau.name,
                            token_contract=self.eth.name,
                            tau_out=0,
                            token_out=expected_output_amount,
                            to_address='test_results_wallet')
        # Validate Wallet Balances Post Swap
        wallet_balance_tau = self.tau.balance_of(account='test_results_wallet')
        self.assertEqual(wallet_balance_tau, 0.0)
        wallet_balance_token = self.eth.balance_of(
            account='test_results_wallet')
        self.assertEqual(wallet_balance_token, expected_output_amount)

        # Validate Reserves
        tau_reserve, token_reserve = self.dex_pairs.get_pair_reserves(
            tau_contract=self.tau.name, token_contract=self.eth.name)

        self.assertEqual(tau_reserve, tau_amount + swap_amount)
        self.assertEqual(token_reserve, token_amount - expected_output_amount)

        # Validate Balances + AMM Reserves Post-Swap
        pair_balance_tau = self.tau.balance_of(account=self.dex_pairs.name)
        self.assertEqual(pair_balance_tau, tau_amount + swap_amount)
        pair_balance_token = self.eth.balance_of(account=self.dex_pairs.name)
        self.assertEqual(pair_balance_token,
                         token_amount - expected_output_amount)

        # TODO - A4 - Token Supply Validations.
        # Validate Supply @ UniswapV2Pair.specs.ts
        total_supply = self.dex_pairs.total_supply(
            tau_contract=self.tau.name, token_contract=self.eth.name)

    def test_3_token1_swap(self):
        self.change_signer(self.wallet_address)

        tau_amount = 5
        token_amount = 10

        self.add_liquidity(tau_amount, token_amount)

        swap_amount = 1
        expected_output_amount = self.expand_to_token_decimals(
            453305446940074565)

        self.eth.transfer(amount=swap_amount, to=self.dex_pairs.name)

        # TODO - A4 - Asserts on Emit()
        self.dex_pairs.swap(tau_contract=self.tau.name,
                            token_contract=self.eth.name,
                            tau_out=expected_output_amount,
                            token_out=0,
                            to_address='test_results_wallet')

        # Validate Wallet Balances Post Swap
        wallet_balance_tau = self.tau.balance_of(account='test_results_wallet')
        self.assertEqual(wallet_balance_tau, expected_output_amount)
        wallet_balance_token = self.eth.balance_of(
            account='test_results_wallet')
        self.assertEqual(wallet_balance_token, 0.0)

        # Validate Reserves
        tau_reserve, token_reserve = self.dex_pairs.get_pair_reserves(
            tau_contract=self.tau.name, token_contract=self.eth.name)

        self.assertEqual(tau_reserve, tau_amount - expected_output_amount)
        self.assertEqual(token_reserve, token_amount + swap_amount)

        # Validate Balances + AMM Reserves Post-Swap
        pair_balance_tau = self.tau.balance_of(account=self.dex_pairs.name)
        self.assertEqual(pair_balance_tau, tau_amount - expected_output_amount)
        pair_balance_token = self.eth.balance_of(account=self.dex_pairs.name)
        self.assertEqual(pair_balance_token, token_amount + swap_amount)

        # TODO - A4 - Token Supply Validations.
        # Validate Supply @ UniswapV2Pair.specs.ts
        total_supply = self.dex_pairs.total_supply(
            tau_contract=self.tau.name, token_contract=self.eth.name)

    def test_4_burn(self):
        self.change_signer(self.wallet_address)

        tau_amount = 3
        token_amount = 3

        # Add liquidity
        self.add_liquidity(tau_amount, token_amount)

        expected_liquidity = 3

        self.dex_pairs.transfer(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            amount=expected_liquidity -
            self.expand_to_token_decimals(MINIMUM_LIQUIDITY),
            to=self.dex_pairs.name)

        dex_pair_lp_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.dex_pairs.name)
        assert dex_pair_lp_balance == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

        # transfer, transfer, transfer, sync, burn
        tau_amount, token_amount = self.dex_pairs.burn_liquidity(
            dex_contract=self.dex.name,
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            to_address=self.wallet_address)

        # Assert we got back everything - MINIMUM LIQUIDITY
        assert tau_amount == token_amount
        assert tau_amount == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)
        assert token_amount == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

        tau_wallet_balance = self.tau.balance_of(account=self.wallet_address)
        assert tau_wallet_balance == STARTING_BALANCE - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)
        token_wallet_balance = self.eth.balance_of(account=self.wallet_address)
        assert token_wallet_balance == STARTING_BALANCE - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

        # Assert that remaining balance of liquidity for wallet is 0
        assert self.dex_pairs.balance_of(tau_contract=self.tau.name,
                                         token_contract=self.eth.name,
                                         account=self.wallet_address) == 0
        # assert total supply left for token pair is the MINIMUM_LIQUIDITY
        assert self.dex_pairs.total_supply(
            tau_contract=self.tau.name,
            token_contract=self.eth.name) == self.expand_to_token_decimals(
                MINIMUM_LIQUIDITY)

        # assert total currency left on currencies is only the minimum liquidity
        assert self.tau.balance_of(
            account=self.dex_pairs.name) == self.expand_to_token_decimals(
                MINIMUM_LIQUIDITY)
        assert self.eth.balance_of(
            account=self.dex_pairs.name) == self.expand_to_token_decimals(
                MINIMUM_LIQUIDITY)

    # Test = Dex.fee_to is not initialized (feeTo is Off)
    def test_5_feeTo_off(self):
        tau_amount = 1000
        eth_amount = 1000
        self.add_liquidity(tau_amount, eth_amount)

        swap_amount = 1
        expected_output_amount = self.expand_to_token_decimals(
            996006981039903216)
        self.eth.transfer(amount=swap_amount, to=self.dex_pairs.name)
        self.dex_pairs.swap(tau_contract=self.tau.name,
                            token_contract=self.eth.name,
                            tau_out=expected_output_amount,
                            token_out=0,
                            to_address='test_results_wallet')

        # Validate Reserves
        tau_reserve, token_reserve = self.dex_pairs.get_pair_reserves(
            tau_contract=self.tau.name, token_contract=self.eth.name)
        self.assertEqual(tau_reserve, tau_amount - expected_output_amount)
        self.assertEqual(token_reserve, eth_amount + swap_amount)

        wallet_balance_tau = self.tau.balance_of(account='test_results_wallet')
        wallet_balance_token = self.eth.balance_of(
            account='test_results_wallet')
        self.assertEqual(wallet_balance_tau, expected_output_amount)
        self.assertEqual(wallet_balance_token, 0)

        expected_liquidity = 1000

        self.dex_pairs.transfer(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            amount=expected_liquidity -
            self.expand_to_token_decimals(MINIMUM_LIQUIDITY),
            to=self.dex_pairs.name)

        dex_pair_lp_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.dex_pairs.name)
        assert dex_pair_lp_balance == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

        self.dex_pairs.burn_liquidity(dex_contract=self.dex.name,
                                      tau_contract=self.tau.name,
                                      token_contract=self.eth.name,
                                      to_address=self.wallet_address)

        # Total supply remains as MINIMUM LIQUIDITY
        pair_total_supply = self.dex_pairs.total_supply(
            tau_contract=self.tau.name, token_contract=self.eth.name)
        assert pair_total_supply == self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

    # Test = Dex.fee_to gets initialized (feeTo is On)
    def test_5_feeTo_on(self):
        # Initialize dex.fee_to
        self.change_signer(self.fee_to_setter_address)
        self.dex.set_fee_to(account=self.fee_to_address)

        self.change_signer(self.wallet_address)

        tau_amount = 1000
        eth_amount = 1000
        self.add_liquidity(tau_amount, eth_amount)

        swap_amount = 1
        expected_output_amount = self.expand_to_token_decimals(
            996006981039903216)
        self.eth.transfer(amount=swap_amount, to=self.dex_pairs.name)
        self.dex_pairs.swap(tau_contract=self.tau.name,
                            token_contract=self.eth.name,
                            tau_out=expected_output_amount,
                            token_out=0,
                            to_address='test_results_wallet')

        # Validate Reserves
        tau_reserve, token_reserve = self.dex_pairs.get_pair_reserves(
            tau_contract=self.tau.name, token_contract=self.eth.name)
        self.assertEqual(tau_reserve, tau_amount - expected_output_amount)
        self.assertEqual(token_reserve, eth_amount + swap_amount)

        wallet_balance_tau = self.tau.balance_of(account='test_results_wallet')
        wallet_balance_token = self.eth.balance_of(
            account='test_results_wallet')
        self.assertEqual(wallet_balance_tau, expected_output_amount)
        self.assertEqual(wallet_balance_token, 0)

        expected_liquidity = 1000

        self.dex_pairs.transfer(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            amount=expected_liquidity -
            self.expand_to_token_decimals(MINIMUM_LIQUIDITY),
            to=self.dex_pairs.name)

        dex_pair_lp_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.dex_pairs.name)
        assert dex_pair_lp_balance == expected_liquidity - self.expand_to_token_decimals(
            MINIMUM_LIQUIDITY)

        self.dex_pairs.burn_liquidity(dex_contract=self.dex.name,
                                      tau_contract=self.tau.name,
                                      token_contract=self.eth.name,
                                      to_address=self.wallet_address)

        # Total supply remains as MINIMUM LIQUIDITY
        # ContractingDecimal carries more precision than Ethereum bigNumber
        # assert to 17 places
        expected_supply = self.expand_to_token_decimals(249750499251388 +
                                                        MINIMUM_LIQUIDITY)
        pair_total_supply = self.dex_pairs.total_supply(
            tau_contract=self.tau.name, token_contract=self.eth.name)
        self.assertAlmostEqual(pair_total_supply, expected_supply, places=17)

        fee_to_balance = self.dex_pairs.balance_of(
            tau_contract=self.tau.name,
            token_contract=self.eth.name,
            account=self.fee_to_address)
        expected_fee_to_balance = self.expand_to_token_decimals(
            249750499251388)
        self.assertAlmostEqual(fee_to_balance,
                               expected_fee_to_balance,
                               places=17)

        tau_balance = self.tau.balance_of(account=self.dex_pairs.name)
        expected_tau_balance = self.expand_to_token_decimals(249501683697445 +
                                                             MINIMUM_LIQUIDITY)
        self.assertAlmostEqual(tau_balance, expected_tau_balance, places=17)

        token_balance = self.eth.balance_of(account=self.dex_pairs.name)
        expected_token_balance = self.expand_to_token_decimals(
            250000187312969 + MINIMUM_LIQUIDITY)
        self.assertAlmostEqual(token_balance,
                               expected_token_balance,
                               places=17)
Ejemplo n.º 20
0
class TestPendingMasters(TestCase):
    def setUp(self):
        self.client = ContractingClient()

        f = open('./contracts/currency.s.py')
        self.client.submit(f.read(), 'currency')
        f.close()

        f = open('./contracts/election_house.s.py')
        self.client.submit(f.read(), 'election_house')
        f.close()

        f = open('./contracts/stamp_cost.s.py')
        self.client.submit(f.read(),
                           'stamp_cost',
                           owner='election_house',
                           constructor_args={'initial_rate': 20_000})
        f.close()

        f = open('./contracts/masternodes.s.py')
        self.client.submit(f.read(),
                           'masternodes',
                           owner='election_house',
                           constructor_args={
                               'initial_masternodes': ['stu', 'raghu'],
                               'initial_open_seats': 0
                           })
        f.close()

        self.client.submit(pending_masters)

        self.pending_masters = self.client.get_contract(name='pending_masters')
        self.currency = self.client.get_contract(name='currency')

        self.stamp_cost = self.client.get_contract(name='stamp_cost')
        self.election_house = self.client.get_contract(name='election_house')
        self.election_house.register_policy(contract='stamp_cost')

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

    def test_register(self):
        self.pending_masters.register(signer='stu')
        q = self.pending_masters.Q.get()

        self.assertEqual(q['stu'], 0)

    def test_register_twice_throws_assertion_error(self):
        self.pending_masters.register(signer='stu')

        with self.assertRaises(AssertionError):
            self.pending_masters.register(signer='stu')

    def test_vote_for_someone_not_registered_throws_assertion_error(self):
        with self.assertRaises(AssertionError):
            self.pending_masters.vote(address='stu')

    def test_vote_for_someone_registered_deducts_tau_and_adds_vote(self):
        self.pending_masters.register(signer='joe')

        self.currency.approve(signer='stu',
                              amount=10_000,
                              to='pending_masters')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.pending_masters.vote(signer='stu', address='joe', environment=env)

        self.assertEqual(self.currency.balances['stu'], 999999)
        self.assertEqual(self.pending_masters.Q.get()['joe'], 1)
        self.assertEqual(self.currency.balances['blackhole'], 1)
        self.assertEqual(self.pending_masters.S['last_voted', 'stu'],
                         env['now'])

    def test_voting_again_too_soon_throws_assertion_error(self):
        self.pending_masters.register(signer='joe')

        self.currency.approve(signer='stu',
                              amount=10_000,
                              to='pending_masters')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.pending_masters.vote(signer='stu', address='joe', environment=env)

        with self.assertRaises(AssertionError):
            self.pending_masters.vote(signer='stu',
                                      address='joe',
                                      environment=env)

    def test_voting_again_after_waiting_one_day_works(self):
        self.pending_masters.register(signer='joe')

        self.currency.approve(signer='stu',
                              amount=10_000,
                              to='pending_masters')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.pending_masters.vote(signer='stu', address='joe', environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.pending_masters.vote(signer='stu', address='joe', environment=env)

        self.assertEqual(self.currency.balances['stu'], 999998)
        self.assertEqual(self.pending_masters.Q.get()['joe'], 2)
        self.assertEqual(self.currency.balances['blackhole'], 2)
        self.assertEqual(self.pending_masters.S['last_voted', 'stu'],
                         env['now'])
Ejemplo n.º 21
0
    @export
    def hello():
        return 'Hello World!'

    @export
    def add(a: int, b: int):
        return private_add(a, b)

    def private_add(a, b):
        return a + b


from contracting.client import ContractingClient

# Client to interact with local contracts
client = ContractingClient()

# Submit contract locally
client.submit(greeting)

# List all locally available contracts
print("contracts", client.get_contracts())

# Retrieve local contract
greeting = client.get_contract("greeting")

# Execute contract method 'hello()'
print("greeting - hello()", greeting.hello())
# Execute contract method 'add()'
print("greeting - add()", greeting.add(a=1, b=3))
Ejemplo n.º 22
0
class TestFullFlowWithMocks(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()
        self.driver = ContractDriver(driver=InMemDriver())
        self.client = ContractingClient(driver=self.driver)
        self.client.flush()
        asyncio.set_event_loop(self.loop)

    def tearDown(self):
        self.client.flush()
        self.driver.flush()
        self.ctx.destroy()
        self.loop.close()

    def test_mock_network_init_makes_correct_number_of_nodes(self):
        n = mocks.MockNetwork(num_of_delegates=1, num_of_masternodes=1, ctx=self.ctx)
        self.assertEqual(len(n.masternodes), 1)
        self.assertEqual(len(n.delegates), 1)

    def test_mock_network_init_makes_correct_number_of_nodes_many_nodes(self):
        n = mocks.MockNetwork(num_of_delegates=123, num_of_masternodes=143, ctx=self.ctx)
        self.assertEqual(len(n.masternodes), 143)
        self.assertEqual(len(n.delegates), 123)

    def test_mock_network_init_creates_correct_bootnodes(self):
        # 2 mn, 3 delegate
        expected_ips = [
            'tcp://127.0.0.1:18000',
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002',
            'tcp://127.0.0.1:18003',
            'tcp://127.0.0.1:18004',
        ]

        n = mocks.MockNetwork(num_of_masternodes=2, num_of_delegates=3, ctx=self.ctx)

        self.assertEqual(n.masternodes[0].ip, expected_ips[0])
        self.assertEqual(n.masternodes[1].ip, expected_ips[1])
        self.assertEqual(n.delegates[0].ip, expected_ips[2])
        self.assertEqual(n.delegates[1].ip, expected_ips[3])
        self.assertEqual(n.delegates[2].ip, expected_ips[4])

    def test_startup_with_manual_node_creation_and_single_block_works(self):
        m = mocks.MockMaster(ctx=self.ctx, index=1)
        d = mocks.MockDelegate(ctx=self.ctx, index=2)

        bootnodes = {
            m.wallet.verifying_key: m.ip,
            d.wallet.verifying_key: d.ip
        }

        constitution = {
            'masternodes': [m.wallet.verifying_key],
            'delegates': [d.wallet.verifying_key]
        }

        m.set_start_variables(bootnodes, constitution)
        d.set_start_variables(bootnodes, constitution)

        sender = Wallet()

        async def test():
            await asyncio.gather(
                m.start(),
                d.start()
            )

            tx_1 = transaction.build_transaction(
                wallet=mocks.TEST_FOUNDATION_WALLET,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 1_000_000,
                    'to': sender.verifying_key
                },
                stamps=10000,
                nonce=0,
                processor=m.wallet.verifying_key
            )

            tx_2 = transaction.build_transaction(
                wallet=sender,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 1338,
                    'to': 'jeff'
                },
                stamps=5000,
                nonce=0,
                processor=m.wallet.verifying_key
            )

            async with httpx.AsyncClient() as client:
                await client.post('http://0.0.0.0:18081/', data=tx_1)
                await asyncio.sleep(2)
                await client.post('http://0.0.0.0:18081/', data=tx_2)
                await asyncio.sleep(2)

            await asyncio.sleep(2)

            m.stop()
            d.stop()

        self.loop.run_until_complete(test())

        # dbal = dld.get_var(contract='currency', variable='balances', arguments=['jeff'])
        mbal = m.driver.get_var(contract='currency', variable='balances', arguments=['jeff'])

        # self.assertEqual(dbal, 1338)
        self.assertEqual(mbal, 1338)

    def test_startup_and_blocks_from_network_object_works(self):
        network = mocks.MockNetwork(ctx=self.ctx, num_of_masternodes=1, num_of_delegates=1)

        sender = Wallet()

        async def test():
            await network.start()
            network.refresh()

            await network.make_and_push_tx(
                wallet=mocks.TEST_FOUNDATION_WALLET,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 1_000_000,
                    'to': sender.verifying_key
                }
            )

            await asyncio.sleep(2)

            await network.make_and_push_tx(
                wallet=sender,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 1338,
                    'to': 'jeff'
                }
            )

            await asyncio.sleep(2)

            await network.make_and_push_tx(
                wallet=sender,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 444,
                    'to': 'stu'
                }
            )

            await asyncio.sleep(2)

            network.stop()
Ejemplo n.º 23
0
class TestPendingMasters(TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()

        f = open('./contracts/currency.s.py')
        self.client.submit(f.read(), 'currency')
        f.close()

        f = open('./contracts/election_house.s.py')
        self.client.submit(f.read(), 'election_house')
        f.close()

        f = open('./contracts/stamp_cost.s.py')
        self.client.submit(f.read(),
                           'stamp_cost',
                           owner='election_house',
                           constructor_args={'initial_rate': 20_000})
        f.close()

        f = open('./contracts/members.s.py')
        self.client.submit(
            f.read(),
            'masternodes',
            owner='election_house',
            constructor_args={'initial_members': ['stux', 'raghu']})
        f.close()

        f = open('./contracts/elect_members.s.py')
        self.client.submit(f.read(),
                           'elect_members',
                           constructor_args={'policy': 'masternodes'})
        f.close()

        self.elect_members = self.client.get_contract(name='elect_members')
        self.currency = self.client.get_contract(name='currency')
        self.masternodes = self.client.get_contract(name='masternodes')

        self.stamp_cost = self.client.get_contract(name='stamp_cost')
        self.election_house = self.client.get_contract(name='election_house')
        self.election_house.register_policy(contract='stamp_cost')
        self.election_house.register_policy(contract='masternodes')

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

    def test_register(self):
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')
        self.elect_members.register(signer='stu')
        q = self.elect_members.candidate_state['votes', 'stu']

        self.assertEqual(q, 0)
        self.assertEqual(self.currency.balances['elect_members'], 100_000)
        self.assertEqual(
            self.elect_members.candidate_state['registered', 'stu'], True)

    def test_double_register_raises_assert(self):
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')
        self.elect_members.register(signer='stu')
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')

        with self.assertRaises(AssertionError):
            self.elect_members.register(signer='stu')

    def test_unregister_returns_currency(self):
        b1 = self.currency.balances['stu']
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')
        self.elect_members.register(signer='stu')

        self.assertEqual(self.currency.balances['stu'], b1 - 100_000)

        self.elect_members.unregister(signer='stu')

        self.assertEqual(self.currency.balances['stu'], b1)

    def test_unregister_if_in_masternodes_throws_assert(self):
        self.currency.approve(signer='stu', amount=100_000, to='elect_members')
        self.elect_members.register(signer='stu')

        self.masternodes.S['masternodes'] = ['stu', 'raghu']

        with self.assertRaises(AssertionError):
            self.elect_members.unregister()

    def test_unregister_if_not_registered_throws_assert(self):
        with self.assertRaises(AssertionError):
            self.elect_members.unregister()

    def test_vote_for_someone_not_registered_throws_assertion_error(self):
        with self.assertRaises(AssertionError):
            self.elect_members.vote_candidate(address='stu')

    def test_vote_for_someone_registered_deducts_tau_and_adds_vote(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe', amount=100_000, to='elect_members')

        self.elect_members.register(signer='joe')

        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}

        stu_bal = self.currency.balances['stu']

        self.elect_members.vote_candidate(signer='stu',
                                          address='joe',
                                          environment=env)

        self.assertEqual(self.currency.balances['stu'], stu_bal - 1)
        self.assertEqual(self.elect_members.candidate_state['votes', 'joe'], 1)
        self.assertEqual(self.currency.balances['blackhole'], 1)
        self.assertEqual(
            self.elect_members.candidate_state['last_voted', 'stu'],
            env['now'])

    def test_voting_again_too_soon_throws_assertion_error(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe', amount=100_000, to='elect_members')

        self.elect_members.register(signer='joe')

        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_candidate(signer='stu',
                                          address='joe',
                                          environment=env)

        with self.assertRaises(AssertionError):
            self.elect_members.vote_candidate(signer='stu',
                                              address='joe',
                                              environment=env)

    def test_voting_again_after_waiting_one_day_works(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe', amount=100_000, to='elect_members')

        self.elect_members.register(signer='joe')

        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        stu_bal = self.currency.balances['stu']

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_candidate(signer='stu',
                                          address='joe',
                                          environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.elect_members.vote_candidate(signer='stu',
                                          address='joe',
                                          environment=env)

        self.assertEqual(self.currency.balances['stu'], stu_bal - 2)
        self.assertEqual(self.elect_members.candidate_state['votes', 'joe'], 2)

        self.assertEqual(self.currency.balances['blackhole'], 2)

        self.assertEqual(
            self.elect_members.candidate_state['last_voted', 'stu'],
            env['now'])

    def test_top_masternode_returns_none_if_no_candidates(self):
        self.assertIsNone(self.elect_members.top_member())

    def test_top_masternode_returns_joe_if_registered_but_no_votes(self):
        self.currency.transfer(signer='stu', amount=100_000,
                               to='joe')  # Give joe money
        self.currency.approve(signer='joe', amount=100_000,
                              to='elect_members')  # Joe Allows Spending
        self.elect_members.register(signer='joe')  # Register Joe

        self.assertEqual(self.elect_members.top_member(),
                         'joe')  # Joe is the current top spot

    def test_top_masternode_returns_bob_if_joe_and_bob_registered_but_bob_has_votes(
            self):
        self.currency.transfer(signer='stu', amount=100_000,
                               to='joe')  # Give joe money
        self.currency.approve(signer='joe', amount=100_000,
                              to='elect_members')  # Joe Allows Spending
        self.elect_members.register(signer='joe')  # Register Joe

        self.currency.transfer(signer='stu', amount=100_000,
                               to='bob')  # Give Bob money
        self.currency.approve(signer='bob', amount=100_000,
                              to='elect_members')  # Bob Allows Spending
        self.elect_members.register(signer='bob')  # Register Bob

        self.currency.approve(
            signer='stu', amount=10_000,
            to='elect_members')  # Stu approves spending to vote
        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_candidate(signer='stu',
                                          address='bob',
                                          environment=env)  # Stu votes for Bob

        self.assertEqual(self.elect_members.top_member(),
                         'bob')  # bob is the current top spot

    def test_top_masternode_returns_joe_if_joe_and_bob_registered_but_joe_first_and_no_votes(
            self):
        self.currency.transfer(signer='stu', amount=100_000,
                               to='joe')  # Give joe money
        self.currency.approve(signer='joe', amount=100_000,
                              to='elect_members')  # Joe Allows Spending
        self.elect_members.register(signer='joe')  # Register Joe

        self.currency.transfer(signer='stu', amount=100_000,
                               to='bob')  # Give Bob money
        self.currency.approve(signer='bob', amount=100_000,
                              to='elect_members')  # Bob Allows Spending
        self.elect_members.register(signer='bob')  # Register Bob

        self.assertEqual(self.elect_members.top_member(),
                         'joe')  # Joe is the current top spot

    def test_pop_top_fails_if_not_masternodes_contract(self):
        with self.assertRaises(AssertionError):
            self.elect_members.pop_top()

    def test_pop_top_doesnt_fail_if_masternode_contract(self):
        self.elect_members.pop_top(signer='masternodes')

    def test_pop_top_deletes_bob_if_pop_is_top_masternode(self):
        self.currency.transfer(signer='stu', amount=100_000,
                               to='joe')  # Give joe money
        self.currency.approve(signer='joe', amount=100_000,
                              to='elect_members')  # Joe Allows Spending
        self.elect_members.register(signer='joe')  # Register Joe

        self.currency.transfer(signer='stu', amount=100_000,
                               to='bob')  # Give Bob money
        self.currency.approve(signer='bob', amount=100_000,
                              to='elect_members')  # Bob Allows Spending
        self.elect_members.register(signer='bob')  # Register Bob

        self.currency.approve(
            signer='stu', amount=10_000,
            to='elect_members')  # Stu approves spending to vote
        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_candidate(signer='stu',
                                          address='bob',
                                          environment=env)  # Stu votes for Bob

        self.assertEqual(self.elect_members.top_member(),
                         'bob')  # bob is the current top spot

        self.assertIsNotNone(self.elect_members.candidate_state['votes',
                                                                'bob'])

        self.elect_members.pop_top(signer='masternodes')

        self.assertIsNone(self.elect_members.candidate_state['votes', 'bob'])

    def test_pop_top_returns_none_if_noone_registered(self):
        self.assertIsNone(self.elect_members.pop_top(signer='masternodes'))

    def test_voting_no_confidence_against_non_committee_member_fails(self):
        with self.assertRaises(AssertionError):
            self.elect_members.vote_no_confidence(address='whoknows')

    def test_vote_no_confidence_for_someone_registered_deducts_tau_and_adds_vote(
            self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        stu_bal = self.currency.balances['stu']

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_no_confidence(
            signer='stu', address='raghu',
            environment=env)  # Raghu is seeded in contract

        self.assertEqual(self.currency.balances['stu'], stu_bal - 1)
        self.assertEqual(
            self.elect_members.no_confidence_state['votes', 'raghu'], 1)
        self.assertEqual(self.currency.balances['blackhole'], 1)
        self.assertEqual(
            self.elect_members.no_confidence_state['last_voted', 'stu'],
            env['now'])

    def test_voting_no_confidence_again_too_soon_throws_assertion_error(self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        with self.assertRaises(AssertionError):
            self.elect_members.vote_no_confidence(signer='stu',
                                                  address='raghu',
                                                  environment=env)

    def test_voting_no_confidence_again_after_waiting_one_day_works(self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        stu_bal = self.currency.balances['stu']

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        self.assertEqual(self.currency.balances['stu'], stu_bal - 2)
        self.assertEqual(
            self.elect_members.no_confidence_state['votes', 'raghu'], 2)

        self.assertEqual(self.currency.balances['blackhole'], 2)

        self.assertEqual(
            self.elect_members.no_confidence_state['last_voted', 'stu'],
            env['now'])

    def test_last_masternode_returns_none_if_no_candidates(self):
        self.assertIsNone(self.elect_members.last_member())

    def test_last_masternode_returns_none_if_no_votes(self):
        self.assertEqual(self.elect_members.last_member(),
                         None)  # Joe is the current top spot

    def test_relinquish_fails_if_not_in_masternodes(self):
        with self.assertRaises(AssertionError):
            self.elect_members.relinquish(signer='joebob')

    def test_relinquish_adds_ctx_signer_if_in_masternodes(self):
        self.elect_members.relinquish(signer='raghu')

        self.assertEqual('raghu', self.elect_members.to_be_relinquished.get())

    def test_last_masternode_returns_relinquished_if_there_is_one_to_be_relinquished(
            self):
        self.elect_members.relinquish(signer='raghu')

        self.assertEqual(self.elect_members.last_member(), 'raghu')

    def test_error_if_someone_tries_to_relinquish_when_another_exists(self):
        self.elect_members.relinquish(signer='raghu')
        with self.assertRaises(AssertionError):
            self.elect_members.relinquish(signer='stux')

    def test_last_masternode_returns_masternode_with_most_votes_if_none_in_relinquished(
            self):
        self.currency.approve(
            signer='stu', amount=10_000,
            to='elect_members')  # Stu approves spending to vote
        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_no_confidence(
            signer='stu', address='raghu',
            environment=env)  # Stu votes for Bob

        self.assertEqual(self.elect_members.last_member(),
                         'raghu')  # bob is the current top spot

    def test_last_masternode_returns_first_in_if_tie(self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}

        self.elect_members.vote_no_confidence(signer='stu',
                                              address='stux',
                                              environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        self.assertEqual(self.elect_members.last_member(), 'stux')

    def test_last_masternode_returns_least_popular_if_multiple_votes(self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='stux',
                                              environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=14))}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='stux',
                                              environment=env)

        self.assertEqual(self.elect_members.last_member(), 'stux')

    def test_pop_last_fails_if_not_masternodes_contract(self):
        with self.assertRaises(AssertionError):
            self.elect_members.pop_last()

    def test_pop_last_doesnt_fail_if_masternodes_contract(self):
        self.elect_members.pop_last(signer='masternodes')

    def test_pop_last_deletes_stux_if_is_last_masternode_and_no_relinquished(
            self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='stux',
                                              environment=env)

        self.assertIsNotNone(self.elect_members.no_confidence_state['votes',
                                                                    'stux'])
        self.elect_members.pop_last(signer='masternodes')
        self.assertIsNone(self.elect_members.no_confidence_state['votes',
                                                                 'stux'])

    def test_pop_last_deletes_raghu_if_stux_voted_but_raghu_relinquished(self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='stux',
                                              environment=env)

        self.elect_members.relinquish(signer='raghu')

        self.assertIsNotNone(self.elect_members.no_confidence_state['votes',
                                                                    'stux'])
        self.assertIn('raghu', self.elect_members.to_be_relinquished.get())

        self.elect_members.pop_last(signer='masternodes')

        self.assertIsNone(self.elect_members.to_be_relinquished.get())
        self.assertIsNotNone(self.elect_members.no_confidence_state['votes',
                                                                    'stux'])

    def test_pop_last_deletes_raghu_from_no_confidence_hash_if_relinquished(
            self):
        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        env = {'now': Datetime._from_datetime(dt.today())}
        self.elect_members.vote_no_confidence(signer='stu',
                                              address='raghu',
                                              environment=env)

        self.elect_members.relinquish(signer='raghu')

        self.assertIsNotNone(self.elect_members.no_confidence_state['votes',
                                                                    'raghu'])
        self.assertIn('raghu', self.elect_members.to_be_relinquished.get())

        self.elect_members.pop_last(signer='masternodes')

        self.assertIsNone(self.elect_members.to_be_relinquished.get())
        self.assertEqual(
            self.elect_members.no_confidence_state['votes', 'raghu'], 0)

    def test_no_confidence_pop_last_prevents_unregistering(self):
        # Give Raghu money
        self.currency.transfer(signer='stu', amount=100_000, to='raghu')

        # Raghu Allows Spending
        self.currency.approve(signer='raghu',
                              amount=100_000,
                              to='elect_members')

        self.elect_members.register(signer='raghu')

        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        self.elect_members.vote_no_confidence(signer='stu', address='raghu')

        self.elect_members.pop_last(signer='masternodes')

        self.assertFalse(self.elect_members.candidate_state['registered',
                                                            'raghu'])

        with self.assertRaises(AssertionError):
            self.elect_members.unregister(signer='raghu')

    def test_relinquish_pop_last_allows_unregistering(self):
        # Give Raghu money
        self.currency.transfer(signer='stu', amount=100_000, to='raghu')

        # Raghu Allows Spending
        self.currency.approve(signer='raghu',
                              amount=100_000,
                              to='elect_members')

        self.elect_members.register(signer='raghu')

        self.currency.approve(signer='stu', amount=10_000, to='elect_members')

        self.elect_members.vote_no_confidence(signer='stu', address='raghu')
        self.elect_members.relinquish(signer='raghu')
        self.elect_members.pop_last(signer='masternodes')

        self.assertTrue(self.elect_members.candidate_state['registered',
                                                           'raghu'])
        self.masternodes.quick_write('S', 'members', ['stu'])
        self.elect_members.unregister(signer='raghu')

    def test_force_removal_fails_if_not_masternodes(self):
        with self.assertRaises(AssertionError):
            self.elect_members.force_removal(address='stux')

    def test_force_removal_unregisters_address(self):
        # Give Raghu money
        self.currency.transfer(signer='stu', amount=100_000, to='stux')

        # Raghu Allows Spending
        self.currency.approve(signer='stux',
                              amount=100_000,
                              to='elect_members')

        self.elect_members.register(signer='stux')
        self.elect_members.force_removal(signer='masternodes', address='stux')
        self.assertFalse(self.elect_members.candidate_state['registered',
                                                            'stux'])
Ejemplo n.º 24
0
class TestMasternodePolicy(TestCase):
    def setUp(self):
        self.client = ContractingClient()

        f = open('./contracts/currency.s.py')
        self.client.submit(f.read(), 'currency')
        f.close()

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

        self.client.submit(contract, name='election_house')

        f = open('./contracts/master_candidates.s.py')
        self.client.submit(f.read(), 'master_candidates')
        f.close()

        f = open('./contracts/stamp_cost.s.py')
        self.client.submit(f.read(),
                           'stamp_cost',
                           owner='election_house',
                           constructor_args={'initial_rate': 20_000})
        f.close()

        self.election_house = self.client.get_contract('election_house')
        self.stamp_cost = self.client.get_contract(name='stamp_cost')
        self.election_house.register_policy(contract='stamp_cost')
        self.master_candidates = self.client.get_contract('master_candidates')
        self.currency = self.client.get_contract('currency')

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

    def test_init(self):
        self.client.submit(masternodes,
                           owner='election_house',
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        self.assertEqual(mn_contract.current_value(signer='election_house'),
                         [1, 2, 3])

        self.assertEqual(mn_contract.S['yays'], 0)
        self.assertEqual(mn_contract.S['nays'], 0)
        self.assertEqual(mn_contract.S['current_motion'], 0)

    def test_voter_not_masternode_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk='sys',
                                             action='introduce_motion',
                                             position=1)

    def test_vote_invalid_action_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='xxx',
                                             position=1)

    def test_vote_on_motion_bool_succeeds(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.run_private_function(f='assert_vote_is_valid',
                                         vk=1,
                                         action='vote_on_motion',
                                         position=True)

    def test_action_introduce_motion_current_motion_not_no_motion_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write(variable='S', key='current_motion', value=1)

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1)

    def test_action_introduce_motion_out_of_range_motion_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=10)

    def test_action_introduce_motion_no_arg_provided_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1)

    def test_action_introduce_motion_vk_not_str_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg=True)

    def test_action_introduce_motion_vk_not_64_chars_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg='a')

    def test_action_introduce_motion_not_valid_hex_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(ValueError):
            mn_contract.run_private_function(f='assert_vote_is_valid',
                                             vk=1,
                                             action='introduce_motion',
                                             position=1,
                                             arg='x' * 64,
                                             signer='x' * 64)

    def test_action_vote_on_motion_fails_if_not_bool(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='assert_vote_is_valid',
                vk=1,
                action='vote_on_motion',
                position=1,
            )

    def test_vote_not_tuple_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 'sys'],
                           })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='sys', obj={'hanky': 'panky'})

    def test_vote_1_elem_tuple_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 'sys'],
                           })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(ValueError):
            mn_contract.vote(vk='sys', obj=(1, ))

    def test_vote_4_elem_tuple_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 'sys'],
                           })

        mn_contract = self.client.get_contract('masternodes')
        with self.assertRaises(ValueError):
            mn_contract.vote(vk='sys', obj=(1, 2, 3, 4))

    # ADD_MASTER = 1
    # REMOVE_MASTER = 2
    # ADD_SEAT = 3
    # REMOVE_SEAT = 4

    def test_introduce_motion_remove_seat_fails_if_position_out_of_index(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(f='introduce_motion',
                                             position=4,
                                             arg=None)

    def test_introduce_motion_remove_seat_works_and_sets_position_and_motion_opened(
            self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'open_seats', 1)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        mn_contract.run_private_function(f='introduce_motion',
                                         position=3,
                                         arg=None,
                                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 3)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])

    def test_add_master_or_remove_master_adds_arg(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': ['abc', 'bcd', 'cde'],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'open_seats', 1)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=7))}

        mn_contract.run_private_function(f='introduce_motion',
                                         position=1,
                                         arg='abc',
                                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 1)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])
        self.assertEqual(mn_contract.quick_read('S', 'master_in_question'),
                         'abc')

    def test_remove_master_that_does_not_exist_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        with self.assertRaises(AssertionError):
            mn_contract.run_private_function(
                f='introduce_motion',
                position=1,
                arg='abc',
            )

    def test_remove_master_that_exists_passes(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.run_private_function(
            f='introduce_motion',
            position=2,
            arg=1,
        )

    def test_pass_current_motion_add_master_appends_and_removes_seat(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe',
                              amount=100_000,
                              to='master_candidates')

        self.master_candidates.register(signer='joe')

        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'current_motion', 2)

        mn_contract.run_private_function(f='pass_current_motion', )

        self.assertEqual(mn_contract.quick_read('S', 'masternodes'),
                         [1, 2, 3, 'joe'])

    def test_pass_current_motion_remove_master_adds_new_seat_and_removes_master(
            self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'master_in_question', 1)
        mn_contract.quick_write('S', 'current_motion', 1)

        mn_contract.run_private_function(f='pass_current_motion', )

        self.assertEqual(mn_contract.quick_read('S', 'masternodes'), [2, 3])

    def test_pass_remove_seat_removes_least_popular(self):
        self.client.submit(masternodes,
                           owner='election_house',
                           constructor_args={
                               'initial_masternodes': ['abc', 'bcd', 'def'],
                           })
        self.election_house.register_policy(contract='masternodes')
        self.currency.approve(signer='stu',
                              amount=100_000,
                              to='master_candidates')

        self.master_candidates.vote_no_confidence(signer='stu', address='bcd')

        self.election_house.vote(signer='abc',
                                 policy='masternodes',
                                 value=('introduce_motion', 3))
        self.election_house.vote(signer='bcd',
                                 policy='masternodes',
                                 value=('vote_on_motion', True))
        self.election_house.vote(signer='def',
                                 policy='masternodes',
                                 value=('vote_on_motion', True))

        self.assertListEqual(
            self.election_house.current_value_for_policy(policy='masternodes'),
            ['abc', 'def'])

    def test_pass_remove_seat_removes_relinquished_first(self):
        self.client.submit(masternodes,
                           owner='election_house',
                           constructor_args={
                               'initial_masternodes': ['abc', 'bcd', 'def'],
                           })
        self.election_house.register_policy(contract='masternodes')

        self.master_candidates.relinquish(signer='abc')

        self.election_house.vote(signer='abc',
                                 policy='masternodes',
                                 value=('introduce_motion', 3))

        self.election_house.vote(signer='bcd',
                                 policy='masternodes',
                                 value=('vote_on_motion', True))
        self.election_house.vote(signer='def',
                                 policy='masternodes',
                                 value=('vote_on_motion', True))

        self.assertListEqual(
            self.election_house.current_value_for_policy(policy='masternodes'),
            ['bcd', 'def'])

    def test_remove_seat_not_current_masternode_fails(self):
        self.client.submit(masternodes,
                           owner='election_house',
                           constructor_args={
                               'initial_masternodes': ['abc', 'bcd', 'def'],
                           })
        self.election_house.register_policy(contract='masternodes')

        with self.assertRaises(AssertionError):
            self.election_house.vote(signer='abc',
                                     policy='masternodes',
                                     value=('introduce_motion', 1, 'blah'))

    def test_pass_add_seat_adds_most_popular(self):
        # Give joe money
        self.currency.transfer(signer='stu', amount=100_000, to='joe')

        # Joe Allows Spending
        self.currency.approve(signer='joe',
                              amount=100_000,
                              to='master_candidates')

        self.master_candidates.register(signer='joe')

        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.vote(vk=1, obj=('introduce_motion', 2))

        mn_contract.vote(vk=2, obj=('vote_on_motion', True))
        mn_contract.vote(vk=3, obj=('vote_on_motion', True))

        self.assertListEqual(mn_contract.current_value(), [1, 2, 3, 'joe'])

    def test_current_value_returns_dict(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        d = mn_contract.current_value()

        self.assertEqual(d, [1, 2, 3])

    # S['current_motion'] = NO_MOTION
    # S['master_in_question'] = None
    # S['votes'] = 0
    # S.clear('positions')
    def test_reset_alters_state_correctly(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes': [1, 2, 3],
                           })

        mn_contract = self.client.get_contract('masternodes')

        mn_contract.quick_write('S', 'current_motion', 1)
        mn_contract.quick_write('S', 'master_in_question', 'abc')
        mn_contract.quick_write('S', 'yays', 100)
        mn_contract.quick_write('S', 'nays', 999)
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id1'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id2'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id3'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id4'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id5'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id6'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id7'])
        mn_contract.quick_write(variable='S',
                                key='positions',
                                value=[1, 2, 3, 4],
                                args=['id8'])

        mn_contract.run_private_function(f='reset', )

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'master_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id1']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id2']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id3']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id4']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id5']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id6']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id7']))
        self.assertIsNone(
            mn_contract.quick_read('S', 'positions', args=['id8']))

    def test_vote_introduce_motion_affects_state_when_done_properly(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 3)
        self.assertEqual(mn_contract.quick_read('S', 'motion_opened'),
                         env['now'])

    def test_vote_no_motion_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='a' * 64,
                             obj=('vote_on_motion', False),
                             environment=env)

    def test_vote_on_motion_works(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', True))

        self.assertEqual(mn_contract.quick_read('S', 'yays'), 1)
        self.assertEqual(
            mn_contract.quick_read(variable='S',
                                   key='positions',
                                   args=['b' * 64]), True)

    def test_vote_on_motion_works_nays(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', False))

        self.assertEqual(mn_contract.quick_read('S', 'nays'), 1)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)
        self.assertEqual(
            mn_contract.quick_read(variable='S',
                                   key='positions',
                                   args=['b' * 64]), False)

    def test_vote_on_motion_twice_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', True))

        with self.assertRaises(AssertionError):
            mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', False))

    def test_vote_reaches_more_than_half_passes(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        mn_contract.vote(vk='a' * 64, obj=('vote_on_motion', True))
        mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', True))

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'master_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'yays'), 0)

    def test_vote_reaches_more_than_half_nays_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        mn_contract.vote(vk='a' * 64, obj=('vote_on_motion', False))
        mn_contract.vote(vk='b' * 64, obj=('vote_on_motion', False))

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'master_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)

    def test_vote_doesnt_reach_consensus_after_voting_period_fails(self):
        self.client.submit(masternodes,
                           constructor_args={
                               'initial_masternodes':
                               ['a' * 64, 'b' * 64, 'c' * 64],
                           })

        mn_contract = self.client.get_contract('masternodes')

        env = {'now': Datetime._from_datetime(dt.today())}

        mn_contract.vote(vk='a' * 64,
                         obj=('introduce_motion', 3),
                         environment=env)

        env = {'now': Datetime._from_datetime(dt.today() + td(days=2))}

        mn_contract.vote(vk='a' * 64,
                         obj=('vote_on_motion', True),
                         environment=env)

        self.assertEqual(mn_contract.quick_read('S', 'current_motion'), 0)
        self.assertEqual(mn_contract.quick_read('S', 'master_in_question'),
                         None)
        self.assertEqual(mn_contract.quick_read('S', 'nays'), 0)
Ejemplo n.º 25
0
class TestBetterElectionHouse(TestCase):
    def setUp(self):
        self.client = ContractingClient()
        self.client.flush()
        self.client.submit(election_house, name='election_house2')

        self.election_house = self.client.get_contract(name='election_house2')

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

    def test_register_doesnt_fail(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')

    def test_register_without_owner_fails(self):
        self.client.submit(test_policy)
        with self.assertRaises(AssertionError):
            self.election_house.register_policy(policy='testing',
                                                contract='test_policy')

    def test_register_same_contract_twice_fails(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')

        with self.assertRaises(Exception):
            self.election_house.register_policy(policy='testing',
                                                contract='test_policy')

    def test_register_contract_without_entire_interface_fails(self):
        self.client.submit(test_policy, owner='election_house2')

        with self.assertRaises(Exception):
            self.election_house.register_policy(policy='testing',
                                                contract='bad_interface')

    def test_register_same_contract_under_another_name_fails(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')

        with self.assertRaises(Exception):
            self.election_house.register_policy(policy='testing2',
                                                contract='test_policy')

    def test_current_value_for_policy_returns_correct_value(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')

        res = self.election_house.current_value_for_policy(policy='testing')

        self.assertEqual(res, '1234')

    def test_current_value_for_non_existant_policy_fails(self):
        self.client.submit(test_policy, owner='election_house2')

        with self.assertRaises(AssertionError):
            self.election_house.current_value_for_policy(policy='testing')

    def test_vote_delegate_calls_policy(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')
        self.election_house.vote(policy='testing', value='5678')

    def test_full_vote_flow_works(self):
        self.client.submit(test_policy, owner='election_house2')
        self.election_house.register_policy(policy='testing',
                                            contract='test_policy')
        self.election_house.vote(policy='testing', value='5678')

        res = self.election_house.current_value_for_policy(policy='testing')

        self.assertEqual(res, '5678')
Ejemplo n.º 26
0
class TestBlockManager(TestCase):
    def setUp(self):
        self.loop = asyncio.get_event_loop()
        self.ctx = zmq.asyncio.Context()

        self.client = ContractingClient()

    def tearDown(self):
        self.ctx.destroy()
        self.loop.stop()
        self.client.flush()

    def test_init(self):
        b = Delegate(socket_base='tcp://127.0.0.1',
                     wallet=Wallet(),
                     ctx=self.ctx,
                     bootnodes=bootnodes,
                     constitution=constitution)

    def test_execute_work_single_transaction(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var):
    v.set(var)

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

        self.client.submit(test_contract, name='testing')

        tx = TransactionBuilder(sender='stu',
                                contract='testing',
                                function='set',
                                kwargs={'var': 'jeff'},
                                stamps=100_000,
                                processor=b'\x00' * 32,
                                nonce=0)
        tx.sign(Wallet().signing_key())
        tx.serialize()

        tx_batch = transaction_list_to_transaction_batch([tx.struct],
                                                         wallet=Wallet())

        b = Delegate(socket_base='tcp://127.0.0.1',
                     wallet=Wallet(),
                     ctx=self.ctx,
                     bootnodes=bootnodes,
                     constitution=constitution)

        b.execute_work([(1, tx_batch)])

    def test_execute_multiple_tx_in_batch_returns_correct_sbc(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var):
    v.set(var)

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

        self.client.submit(test_contract, name='testing')

        tx = TransactionBuilder(sender='stu',
                                contract='testing',
                                function='set',
                                kwargs={'var': 'howdy'},
                                stamps=100_000,
                                processor=b'\x00' * 32,
                                nonce=0)
        tx.sign(Wallet().signing_key())
        tx.serialize()

        tx2 = TransactionBuilder(sender='stu',
                                 contract='testing',
                                 function='get',
                                 kwargs={},
                                 stamps=100_000,
                                 processor=b'\x00' * 32,
                                 nonce=0)
        tx2.sign(Wallet().signing_key())
        tx2.serialize()

        tx_batch = transaction_list_to_transaction_batch(
            [tx.struct, tx2.struct], wallet=Wallet())
        w = Wallet()
        b = Delegate(socket_base='tcp://127.0.0.1', wallet=w, ctx=self.ctx)

        results = b.execute_work([(tx_batch.timestamp, tx_batch)])

        # Test that there is a state change on the 1st tx
        tx = results[0].transactions[0]
        self.assertEqual(tx.state[0].key, b'testing.v')
        self.assertEqual(tx.state[0].value, b'"howdy"')

        self.assertEqual(results[0].inputHash, tx_batch.inputHash)
        self.assertEqual(results[0].prevBlockHash, b'\x00' * 32)
        self.assertEqual(results[0].signer, w.verifying_key())

    def test_environment_variables_are_working_as_they_should(self):
        test_contract = '''
a = Variable()
b = Variable()
c = Variable()

@export
def capture():
    a.set(block_hash)
    b.set(block_num)
    c.set(now)
        '''

        self.client.submit(test_contract, name='testing')

        tx = TransactionBuilder(sender='stu',
                                contract='testing',
                                function='capture',
                                kwargs={},
                                stamps=100_000,
                                processor=b'\x00' * 32,
                                nonce=0)
        tx.sign(Wallet().signing_key())
        tx.serialize()

        tx_batch = transaction_list_to_transaction_batch([tx.struct],
                                                         wallet=Wallet())
        w = Wallet()
        b = Delegate(socket_base='tcp://127.0.0.1', wallet=w, ctx=self.ctx)

        now = Datetime._from_datetime(
            datetime.utcfromtimestamp(tx_batch.timestamp))

        results = b.execute_work([(tx_batch.timestamp, tx_batch)])

        tx = results[0].transactions[0]

        a, b, c = tx.state

        self.assertEqual(a.key, b'testing.a')
        self.assertEqual(
            a.value,
            b'"0000000000000000000000000000000000000000000000000000000000000000"'
        )

        self.assertEqual(b.key, b'testing.b')
        self.assertEqual(b.value, b'0')

        self.assertEqual(c.key, b'testing.c')
        self.assertEqual(c.value, encode(now).encode())

    def test_build_sbc_from_work_results(self):
        test_contract = '''
v = Variable()

@construct
def seed():
    v.set('hello')

@export
def set(var):
    v.set(var)

@export
def get():
    return v.get()
        '''
        print('ok')
        self.client.submit(test_contract, name='testing')
        print('here')
        tx = TransactionBuilder(sender='stu',
                                contract='testing',
                                function='set',
                                kwargs={'var': 'jeff'},
                                stamps=100_000,
                                processor=b'\x00' * 32,
                                nonce=0)
        tx.sign(Wallet().signing_key())
        tx.serialize()

        tx_batch = transaction_list_to_transaction_batch([tx.struct],
                                                         wallet=Wallet())

        b = Delegate(socket_base='tcp://127.0.0.1',
                     wallet=Wallet(),
                     ctx=self.ctx,
                     constitution=constitution)

        print(sbc)
Ejemplo n.º 27
0
class TestRewards(TestCase):
    def setUp(self):

        self.client = ContractingClient()
        self.driver = self.client.raw_driver

        # Sync contracts
        sync.submit_from_genesis_json_file(cilantro_ee.contracts.__path__[0] +
                                           '/genesis.json',
                                           client=self.client)
        sync.submit_node_election_contracts(
            initial_masternodes=['stu', 'raghu', 'steve'],
            boot_mns=2,
            initial_delegates=['tejas', 'alex'],
            boot_dels=3,
            client=self.client)

        self.r = RewardManager(driver=self.driver)

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

    def test_add_rewards(self):
        block = random_txs.random_block()

        total = 0

        for sb in block.subBlocks:
            for tx in sb.transactions:
                total += tx.stampsUsed

        self.assertEqual(self.r.stamps_in_block(block), total)

    def test_add_to_balance(self):
        currency_contract = self.client.get_contract('currency')
        current_balance = currency_contract.quick_read(variable='balances',
                                                       key='test')
        if current_balance is None:
            current_balance = 0

        self.assertEqual(current_balance, 0)

        self.r.add_to_balance('test', 1234)

        current_balance = currency_contract.quick_read(variable='balances',
                                                       key='test')
        if current_balance is None:
            current_balance = 0

        self.assertEqual(current_balance, 1234)

        self.r.add_to_balance('test', 1000)

        current_balance = currency_contract.quick_read(variable='balances',
                                                       key='test')
        if current_balance is None:
            current_balance = 0

        self.assertEqual(current_balance, 2234)

    def test_stamps_per_tau_works(self):
        self.assertEqual(self.r.stamps_per_tau, 20_000)

        stamps = self.client.get_contract('stamp_cost')

        stamps.quick_write('S', 'rate', 555)

        self.assertEqual(self.r.stamps_per_tau, 555)

    def test_pending_rewards_get_sets(self):
        self.assertEqual(self.r.get_pending_rewards(), 0)

        self.r.set_pending_rewards(1000)

        self.assertEqual(self.r.get_pending_rewards(), 1000)

    def test_add_pending_rewards(self):
        block = random_txs.random_block()

        total = 0

        for tx in block.subBlocks[0].transactions:
            total += tx.stampsUsed

        expected = ContractingDecimal(total / 100_000)

        self.assertEqual(self.r.get_pending_rewards(), 0)

        self.r.add_pending_rewards(block.subBlocks[0])

        self.assertEqual(self.r.get_pending_rewards(), expected)

    def test_reward_ratio_works(self):
        self.assertEqual(self.r.reward_ratio, [0.5, 0.5, 0, 0])

    def test_issue_rewards_works(self):
        self.r.set_pending_rewards(1000)
        self.r.issue_rewards()

        currency_contract = self.client.get_contract('currency')

        self.r.add_to_balance('raghu', 1000)
        self.r.add_to_balance('steve', 10000)

        self.assertEqual(
            currency_contract.quick_read(variable='balances', key='stu'),
            ContractingDecimal(166.66666666666666))
        self.assertEqual(
            currency_contract.quick_read(variable='balances', key='raghu'),
            ContractingDecimal(1166.66666666666666))
        self.assertEqual(
            currency_contract.quick_read(variable='balances', key='steve'),
            ContractingDecimal(10166.66666666666666))

        self.assertEqual(
            currency_contract.quick_read(variable='balances', key='tejas'),
            250)
        self.assertEqual(
            currency_contract.quick_read(variable='balances', key='alex'), 250)

        self.assertEqual(self.r.get_pending_rewards(), 0)
Ejemplo n.º 28
0
    def setUp(self):
        self.loop = asyncio.get_event_loop()
        self.ctx = zmq.asyncio.Context()

        self.client = ContractingClient()
Ejemplo n.º 29
0
 def setUp(self):
     self.client = ContractingClient()
     self.rewards = rewards.RewardManager()
Ejemplo n.º 30
0
import unittest

from contracting.client import ContractingClient
from exercises.lamdem_blog_sample import my_token
client = ContractingClient()

# SC's get added to DB with each call
# You should either verify before submitting, or wrapping in a try/catch block
running_contracts = client.get_contracts()
if 'my_token' not in running_contracts:
    client.submit(my_token)

# Running into errors when loading it like this.
# I think it might be because of extra headers, and imports
# with open('../exercises/lamdem_blog_sample.py') as f:
#     code = f.read()
#     client.submit(code, name='my_token')


class MyTestCase(unittest.TestCase):
    def test_supply(self):
        my_token = client.get_contract('my_token')
        self.assertEqual(my_token.quick_read('S', 'me'), 50)

    def test_transfer(self):
        # set transaction sender
        client.signer = 'me'

        # get contract reference
        my_token = client.get_contract('my_token')