示例#1
0
文件: mocks.py 项目: baby636/lamden
class MockNode:
    def __init__(self, ctx, index=1, genesis_path=os.path.dirname(os.path.abspath(__file__))):
        self.wallet = Wallet()
        self.index = index
        port = 18000 + index
        self.ip = f'tcp://127.0.0.1:{port}'

        self.raw_driver = Driver(collection=f'state-{self.index}')

        self.driver = ContractDriver(driver=self.raw_driver)
        self.driver.flush()

        self.nonces = storage.NonceStorage(nonce_collection=f'nonces-{self.index}', pending_collection=f'pending-{self.index}')
        self.nonces.flush()

        self.ctx = ctx

        self.bootnodes = {}
        self.constitution = {}
        self.ready_to_start = False
        self.started = False

        self.obj = None
        self.genesis_path = genesis_path

    def set_start_variables(self, bootnodes, constitution):
        self.bootnodes = bootnodes
        self.constitution = constitution
        self.ready_to_start = True

    def flush(self):
        self.driver.flush()
        self.nonces.flush()
示例#2
0
class TestStorage(TestCase):
    def setUp(self):
        self.driver = ContractDriver()
        self.driver.flush()

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

    def test_get_latest_block_hash_0s_if_none(self):
        h = storage.get_latest_block_hash(self.driver)
        self.assertEqual(h, '0' * 64)

    def test_get_latest_block_hash_correct_after_set(self):
        storage.set_latest_block_hash('a' * 64, self.driver)
        h = storage.get_latest_block_hash(self.driver)
        self.assertEqual(h, 'a' * 64)

    def test_get_latest_block_height_0_if_none(self):
        h = storage.get_latest_block_height(self.driver)
        self.assertEqual(h, 0)

    def test_get_latest_block_height_correct_after_set(self):
        storage.set_latest_block_height(123, self.driver)
        h = storage.get_latest_block_height(self.driver)
        self.assertEqual(h, 123)
示例#3
0
class TestSandbox(TestCase):
    def setUp(self):
        self.d = ContractDriver()
        self.d.flush()

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

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

        self.recipients = [secrets.token_hex(16) for _ in range(10000)]

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

    def test_transfer_performance(self):
        e = Executor()

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

        for r in self.recipients:
            e.execute(sender='stu',
                      contract_name='erc20_clone',
                      function_name='transfer',
                      kwargs={
                          'amount': 1,
                          'to': r
                      })
    def test_init_state(self):
        driver = ContractDriver()
        driver.flush()

        sync.sync_genesis_contracts()

        upg = driver.get_contract_keys('upgrade')
        self.assertIsNotNone(upg)
        print('done')
示例#5
0
    def test_sync_genesis_contracts_if_none_in_instance(self):
        driver = ContractDriver()
        driver.flush()

        sync.sync_genesis_contracts()

        submission = driver.get_contract('submission')
        currency = driver.get_contract('currency')
        upgrade = driver.get_contract('upgrade')

        self.assertIsNotNone(submission)
        self.assertIsNotNone(currency)
        self.assertIsNotNone(upgrade)
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_vote_new_delegate(self):
        network = mocks.MockNetwork(num_of_masternodes=2, num_of_delegates=2, ctx=self.ctx)

        stu = Wallet()
        candidate = 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': stu.verifying_key
                }
            )

            await asyncio.sleep(1)

            await network.make_and_push_tx(
                wallet=mocks.TEST_FOUNDATION_WALLET,
                contract='currency',
                function='transfer',
                kwargs={
                    'amount': 1_000_000,
                    'to': candidate.verifying_key
                }
            )
示例#7
0
    def test_submit_contract_with_specific_construction_args(self):
        driver = ContractDriver()
        driver.flush()

        sync.submit_contract_with_construction_args('vkbook',
                                                    args={
                                                        'masternodes':
                                                        ['stu', 'raghu'],
                                                        'delegates':
                                                        ['tejas', 'monica'],
                                                        'num_boot_mns':
                                                        1,
                                                        'num_boot_del':
                                                        1
                                                    })

        client = ContractingClient()
        vkbook = client.get_contract('vkbook')

        self.assertEqual(vkbook.get_masternodes(), ['stu', 'raghu'])
        self.assertEqual(vkbook.get_delegates(), ['tejas', 'monica'])
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()
示例#9
0
class TestMasternode(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()
        self.driver = ContractDriver(driver=InMemDriver())
        asyncio.set_event_loop(self.loop)
        self.authenticator = authentication.SocketAuthenticator(
            client=ContractingClient(driver=self.driver), ctx=self.ctx)

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

    def test_hang_returns_if_not_running(self):
        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18002',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [Wallet().verifying_key],
                                         'delegates': [Wallet().verifying_key]
                                     },
                                     driver=driver)

        self.loop.run_until_complete(node.hang())

    def test_hang_until_tx_queue_has_tx(self):
        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18002',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [Wallet().verifying_key],
                                         'delegates': [Wallet().verifying_key]
                                     },
                                     driver=driver)

        node.running = True

        async def late_tx(timeout=0.2):
            await asyncio.sleep(timeout)
            node.tx_batcher.queue.append('MOCK TX')

        tasks = asyncio.gather(node.hang(), late_tx())

        self.loop.run_until_complete(tasks)

    def test_hang_until_nbn_has_block(self):
        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18002',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [Wallet().verifying_key],
                                         'delegates': [Wallet().verifying_key]
                                     },
                                     driver=driver)

        node.running = True

        async def late_tx(timeout=0.2):
            await asyncio.sleep(timeout)
            node.new_block_processor.q.append('MOCK BLOCK')

        tasks = asyncio.gather(node.hang(), late_tx())

        self.loop.run_until_complete(tasks)

    def test_broadcast_new_chain_does_nothing_if_no_tx(self):
        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18002',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [Wallet().verifying_key],
                                         'delegates': [Wallet().verifying_key]
                                     },
                                     driver=driver)

        node.client.set_var(contract='masternodes',
                            variable='S',
                            arguments=['members'],
                            value=['stu', 'jeff'])

    def test_broadcast_new_chain_sends_messages_to_all_peers(self):
        mn_wallet = Wallet()
        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_router = router.Router(wallet=mn_wallet,
                                  socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True)

        dl_wallet = Wallet()
        dl_bootnode = 'tcp://127.0.0.1:18002'
        dl_router = router.Router(wallet=dl_wallet,
                                  socket_id=dl_bootnode,
                                  ctx=self.ctx,
                                  secure=True)

        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18003',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [mn_wallet.verifying_key],
                                         'delegates':
                                         [dl_wallet.verifying_key]
                                     },
                                     driver=driver)

        node.client.set_var(contract='masternodes',
                            variable='S',
                            arguments=['members'],
                            value=[mn_wallet.verifying_key])

        node.client.set_var(contract='delegates',
                            variable='S',
                            arguments=['members'],
                            value=[dl_wallet.verifying_key])

        node.socket_authenticator.refresh_governance_sockets()

        node.network.peers = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node.tx_batcher.queue.append('MOCK TX')

        tasks = asyncio.gather(mn_router.serve(), dl_router.serve(),
                               node.broadcast_new_blockchain_started(),
                               stop_server(mn_router, 0.2),
                               stop_server(dl_router, 0.2))

        self.loop.run_until_complete(tasks)

    # def test_intermediate_catchup_waits_until_key_in_governance(self):
    #     # A subblock that will have no effect
    #     sbs_1 = {
    #         'transactions': [
    #             {
    #                 'stamps_used': 100,
    #                 'state': [
    #                     {
    #                         'key': 'currency.balances:jeff',
    #                         'value': 10000
    #                     }
    #                 ],
    #                 'transaction': {
    #                     'payload': {
    #                         'sender': 'jeff',
    #                         'nonce': 0,
    #                         'processor': 'stu'
    #                     }
    #                 }
    #             }
    #         ]
    #     }
    #
    #     # A subblock that will add our node to governance
    #     node_wallet = Wallet()
    #     sbs_2 = {
    #         'transactions': [
    #             {
    #                 'stamps_used': 100,
    #                 'state': [
    #                     {
    #                         'key': 'masternodes.S:members',
    #                         'value': [node_wallet.verifying_key]
    #                     }
    #                 ],
    #                 'transaction': {
    #                     'payload': {
    #                         'sender': 'jeff',
    #                         'nonce': 0,
    #                         'processor': 'stu'
    #                     }
    #                 }
    #             }
    #         ]
    #     }
    #
    #     blocks = generate_blocks(2, subblocks=[[sbs_1], [sbs_2]])
    #
    #     driver = ContractDriver(driver=InMemDriver())
    #     node = masternode.Masternode(
    #         socket_base='tcp://127.0.0.1:18003',
    #         ctx=self.ctx,
    #         wallet=node_wallet,
    #         constitution={
    #             'masternodes': [Wallet().verifying_key],
    #             'delegates': [Wallet().verifying_key]
    #         },
    #         driver=driver
    #     )
    #
    #     async def add_block_late(timeout=1):
    #         await asyncio.sleep(timeout)
    #         node.new_block_processor.q.append(blocks[1])
    #
    #     node.new_block_processor.q.append(blocks[0])
    #     node.running = True
    #
    #     tasks = asyncio.gather(
    #         add_block_late(),
    #         node.intermediate_catchup(),
    #
    #     )
    #
    #     self.loop.run_until_complete(tasks)
    #
    #     self.assertTrue(node.running)

    # def test_intermediate_catchup_stops_if_not_running(self):
    #     driver = ContractDriver(driver=InMemDriver())
    #     node_wallet = Wallet()
    #     node = masternode.Masternode(
    #         socket_base='tcp://127.0.0.1:18003',
    #         ctx=self.ctx,
    #         wallet=node_wallet,
    #         constitution={
    #             'masternodes': [Wallet().verifying_key],
    #             'delegates': [Wallet().verifying_key]
    #         },
    #         driver=driver
    #     )
    #
    #     async def stop_late(timeout=1):
    #         await asyncio.sleep(timeout)
    #         node.stop()
    #
    #     tasks = asyncio.gather(
    #         stop_late(),
    #         node.intermediate_catchup(),
    #
    #     )
    #
    #     self.loop.run_until_complete(tasks)
    #
    #     self.assertFalse(node.running)

    def test_send_work_returns_if_no_one_online(self):
        driver = ContractDriver(driver=InMemDriver())
        node_wallet = Wallet()
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18003',
                                     ctx=self.ctx,
                                     wallet=node_wallet,
                                     constitution={
                                         'masternodes':
                                         [Wallet().verifying_key],
                                         'delegates': [Wallet().verifying_key]
                                     },
                                     driver=driver)

        r = self.loop.run_until_complete(node.send_work())

        self.assertFalse(r)

    def test_send_work_multicasts_tx_batch_to_delegates(self):
        ips = [
            'tcp://127.0.0.1:18001', 'tcp://127.0.0.1:18002',
            'tcp://127.0.0.1:18003'
        ]

        d1w = Wallet()
        d2w = Wallet()
        m1w = Wallet()

        self.authenticator.add_verifying_key(d1w.verifying_key)
        self.authenticator.add_verifying_key(d2w.verifying_key)
        self.authenticator.add_verifying_key(m1w.verifying_key)

        self.authenticator.configure()

        d1_r = router.Router(socket_id=ips[0],
                             ctx=self.ctx,
                             wallet=d1w,
                             secure=True)
        d2_r = router.Router(socket_id=ips[1],
                             ctx=self.ctx,
                             wallet=d2w,
                             secure=True)

        d1_q = router.QueueProcessor()
        d2_q = router.QueueProcessor()

        d1_r.add_service(base.WORK_SERVICE, d1_q)
        d2_r.add_service(base.WORK_SERVICE, d2_q)

        node = masternode.Masternode(
            socket_base=ips[2],
            ctx=self.ctx,
            wallet=m1w,
            constitution={
                'masternodes': [m1w.verifying_key],
                'delegates': [d1w.verifying_key, d2w.verifying_key]
            },
            driver=self.driver)

        node.network.peers = {
            d1w.verifying_key: ips[0],
            d2w.verifying_key: ips[1],
            m1w.verifying_key: ips[2]
        }

        tasks = asyncio.gather(d1_r.serve(), d2_r.serve(), node.send_work(),
                               stop_server(d1_r, 1), stop_server(d2_r, 1))

        self.loop.run_until_complete(tasks)

        txb1 = d1_q.q.pop(0)
        txb2 = d2_q.q.pop(0)

        self.assertDictEqual(txb1, txb2)

    def test_new_blockchain_boot_hangs_then_sends_out_broadcast(self):
        mn_wallet = Wallet()
        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_router = router.Router(wallet=mn_wallet,
                                  socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True)

        dl_wallet = Wallet()
        dl_bootnode = 'tcp://127.0.0.1:18002'
        dl_router = router.Router(wallet=dl_wallet,
                                  socket_id=dl_bootnode,
                                  ctx=self.ctx,
                                  secure=True)

        driver = ContractDriver(driver=InMemDriver())
        node = masternode.Masternode(socket_base='tcp://127.0.0.1:18003',
                                     ctx=self.ctx,
                                     wallet=Wallet(),
                                     constitution={
                                         'masternodes':
                                         [mn_wallet.verifying_key],
                                         'delegates':
                                         [dl_wallet.verifying_key]
                                     },
                                     driver=driver)

        node.client.set_var(contract='masternodes',
                            variable='S',
                            arguments=['members'],
                            value=[mn_wallet.verifying_key])

        node.client.set_var(contract='delegates',
                            variable='S',
                            arguments=['members'],
                            value=[dl_wallet.verifying_key])

        node.socket_authenticator.refresh_governance_sockets()

        node.network.peers = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node.tx_batcher.queue.append('MOCK TX')

        node.running = True

        async def late_tx(timeout=0.2):
            await asyncio.sleep(timeout)
            node.tx_batcher.queue.append('MOCK TX')

        async def late_kill(timeout=1):
            node.running = False

        tasks = asyncio.gather(mn_router.serve(), dl_router.serve(), late_tx(),
                               node.new_blockchain_boot(), late_kill(),
                               stop_server(mn_router, 1),
                               stop_server(dl_router, 1))

        self.loop.run_until_complete(tasks)
示例#10
0
class TestAtomicSwapContract(TestCase):
    def setUp(self):
        self.d = ContractDriver()
        self.d.flush()

        with open(contracting.__path__[0] + '/contracts/submission.s.py') as f:
            contract = f.read()

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

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

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

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

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

    def tearDown(self):
        self.e.bypass_privates = False

        self.d.flush()

    def test_initiate_not_enough_approved(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        output = self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5000000
        })

        self.assertEqual(output['status_code'], 1)
        self.assertTrue(isinstance(output['result'], AssertionError))

    def test_initiate_transfers_coins_correctly(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

        atomic_swaps = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account':'atomic_swaps'})
        stu = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account': 'stu'})
        stu_as = self.e.execute('stu', 'erc20_clone', 'allowance', kwargs={'owner': 'stu', 'spender': 'atomic_swaps'})

        self.assertEqual(atomic_swaps['result'], 5)
        self.assertEqual(stu['result'], 999995)
        self.assertEqual(stu_as['result'], 999995)

    def test_initiate_writes_to_correct_key_and_properly(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'}, auto_commit=True)
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        }, auto_commit=True)

        key = 'atomic_swaps.swaps:raghu:eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514'

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

    def test_redeem_on_wrong_secret_fails(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

        output = self.e.execute('raghu', 'atomic_swaps', 'redeem', kwargs={'secret': '00'})

        self.assertEqual(output['status_code'], 1)
        self.assertEqual(str(output['result']), 'Incorrect sender or secret passed.')

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

        output = self.e.execute('stu', 'atomic_swaps', 'redeem', kwargs={'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'})
        # status_code, result, stamps_used
        self.assertEqual(output['status_code'], 1)
        self.assertEqual(str(output['result']), 'Incorrect sender or secret passed.')

    def test_past_expiration_fails(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        output = self.e.execute('raghu', 'atomic_swaps', 'redeem', kwargs={'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                              environment=environment)

        self.assertEqual(output['status_code'], 1)
        self.assertEqual(str(output['result']), 'Swap has expired.')

    def test_successful_redeem_transfers_coins_correctly(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        self.e.execute('raghu', 'atomic_swaps', 'redeem', kwargs={'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

        atomic_swaps = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account': 'atomic_swaps'})
        raghu = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account': 'raghu'})

        self.assertEqual(raghu['result'], 5)
        self.assertEqual(atomic_swaps['result'], 0)

    def test_successful_redeem_deletes_entry(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        self.e.execute('raghu', 'atomic_swaps', 'redeem', kwargs={'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

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

        self.assertEqual(v, None)

    def test_refund_works(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        self.e.execute('stu', 'atomic_swaps', 'refund', kwargs={'participant': 'raghu', 'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

        atomic_swaps = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account': 'atomic_swaps'})
        stu = self.e.execute('stu', 'erc20_clone', 'balance_of', kwargs={'account': 'stu'})

        self.assertEqual(stu['result'], 1000000)
        self.assertEqual(atomic_swaps['result'], 0)

    def test_refund_too_early_fails(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        res = self.e.execute('stu', 'atomic_swaps', 'refund',
                       kwargs={'participant': 'raghu', 'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

        self.assertEqual(str(res['result']), 'Swap has not expired.')

    def test_refund_participant_is_signer_fails(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        res = self.e.execute('raghu', 'atomic_swaps', 'refund',
                       kwargs={'participant': 'raghu', 'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

        self.assertEqual(str(res['result']), 'Caller and signer cannot issue a refund.')

    def test_refund_fails_with_wrong_secret(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        res = self.e.execute('stu', 'atomic_swaps', 'refund',
                                kwargs={'participant': 'raghu', 'secret': '00'},
                                environment=environment)

        self.assertEqual(str(res['result']), 'No swap to refund found.')

    def test_refund_resets_swaps(self):
        self.e.execute('stu', 'erc20_clone', 'approve', kwargs={'amount': 1000000, 'to': 'atomic_swaps'})
        self.e.execute('stu', 'atomic_swaps', 'initiate', kwargs={
            'participant': 'raghu',
            'expiration': Datetime(2020, 1, 1),
            'hashlock': 'eaf48a02d3a4bb3aeb0ecb337f6efb026ee0bbc460652510cff929de78935514',
            'amount': 5
        })

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

        self.e.execute('stu', 'atomic_swaps', 'refund',
                       kwargs={'participant': 'raghu', 'secret': '842b65a7d48e3a3c3f0e9d37eaced0b2'},
                       environment=environment)

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

        self.assertEqual(v, None)

    def test_trying_to_call_private_function_fails(self):
        with self.assertRaises(AssertionError):
            self.e.execute('stu', 'atomic_swaps', '__test', kwargs={})

        self.e.bypass_privates = True

        self.e.execute('stu', 'atomic_swaps', '__test', kwargs={})
示例#11
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_process_two_tx(self):
        network = mocks.MockNetwork(num_of_masternodes=2,
                                    num_of_delegates=2,
                                    ctx=self.ctx)

        stu = Wallet()
        stu2 = Wallet()
        candidate = Wallet()
        candidate2 = Wallet()

        N_tx = 3
        w_stu = []
        for k in range(N_tx):
            w_stu.append(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': w_stu[0].verifying_key
                                           })
            # for k in range(1,N_tx):
            #     await network.make_and_push_tx(
            #         wallet=mocks.TEST_FOUNDATION_WALLET,
            #         contract='currency',
            #         function='transfer',
            #         kwargs={
            #             'amount': 2,
            #             'to': w_stu[0].verifying_key
            #         }
            #     )

            for k1 in range(N_tx - 1):
                # await asyncio.sleep(1)
                k = N_tx - k1 - 2
                await network.make_and_push_tx(
                    wallet=w_stu[k],
                    contract='currency',
                    function='transfer',
                    kwargs={
                        'amount': 10,
                        'to': w_stu[k + 1].verifying_key
                    },
                )
            await asyncio.sleep(2)

            self.assertEqual(
                network.get_var(contract='currency',
                                variable='balances',
                                arguments=[w_stu[N_tx - 1].verifying_key]), 10)
示例#12
0
        contract_code = file.read()

    return {
        'name': contract_name,
        'code': contract_code,
    }


TEST_SUBMISSION_KWARGS = {
    'sender': 'stu',
    'contract_name': 'submission',
    'function_name': 'submit_contract'
}

d = ContractDriver()
d.flush()

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

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

recipients = [secrets.token_hex(16) for _ in range(1000)]

e = Executor()

e.execute(**TEST_SUBMISSION_KWARGS,
          kwargs=submission_kwargs_for_file(
              '../integration/test_contracts/erc20_clone.s.py'))
示例#13
0
class TestDelegate(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)

        self.authenticator = authentication.SocketAuthenticator(
            client=self.client, ctx=self.ctx
        )

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

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

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

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

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

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

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'jeff'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        e = execution.SerialExecutor(executor=self.client.executor)

        result = e.execute_tx(decode(tx), stamp_cost=20_000)

        self.assertEqual(result['status'], 0)
        self.assertEqual(result['state'][0]['key'], 'testing.v')
        self.assertEqual(result['state'][0]['value'],  'jeff')
        self.assertEqual(result['stamps_used'], 1)

    def test_stamp_deduction_on_fail(self):
        test_contract = '''
@export
def eat_stamps():
    while True:
        pass
        '''

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

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        self.client.raw_driver.set(f'currency.balances:{stu.verifying_key}', 100000)

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='eat_stamps',
            kwargs={},
            stamps=10000,
            processor='0' * 64,
            nonce=0
        )

        e = execution.SerialExecutor(executor=self.client.executor)

        self.client.executor.metering = True

        result = e.execute_tx(decode(tx), stamp_cost=200)

        self.assertEqual(result['status'], 1)
        self.assertEqual(result['state'][0]['key'], f'currency.balances:{stu.verifying_key}')
        self.assertEqual(result['state'][0]['value'], Decimal('99950.0'))
        self.assertEqual(result['stamps_used'], 10000)

    def test_generate_environment_creates_datetime_wrapped_object(self):
        timestamp = int(time.time())

        exe = execution.SerialExecutor(executor=self.client.executor)

        e = exe.generate_environment(self.client.raw_driver, timestamp, 'A' * 64)

        t = datetime.utcfromtimestamp(timestamp)

        #self.assertEqual(type(e['now']), Datetime)
        self.assertEqual(e['now'].year, t.year)
        self.assertEqual(e['now'].month, t.month)
        self.assertEqual(e['now'].day, t.day)
        self.assertEqual(e['now'].hour, t.hour)
        self.assertEqual(e['now'].minute, t.minute)
        self.assertEqual(e['now'].second, t.second)

    def test_generate_environment_creates_input_hash(self):
        timestamp = time.time()

        exe = execution.SerialExecutor(executor=self.client.executor)

        e = exe.generate_environment(self.client.raw_driver, timestamp, 'A' * 64)

        self.assertEqual(e['__input_hash'], 'A' * 64)

    def test_generate_environment_creates_block_hash(self):
        timestamp = time.time()

        exe = execution.SerialExecutor(executor=self.client.executor)

        e = exe.generate_environment(self.client.raw_driver, timestamp, 'A' * 64)

        self.assertEqual(e['block_hash'], storage.get_latest_block_hash(self.client.raw_driver))

    def test_generate_environment_creates_block_num(self):
        timestamp = time.time()

        exe = execution.SerialExecutor(executor=self.client.executor)

        e = exe.generate_environment(self.client.raw_driver, timestamp, 'A' * 64)

        self.assertEqual(e['block_num'], storage.get_latest_block_height(self.client.raw_driver) + 1)

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

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

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

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

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

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'howdy'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx = decode(tx)

        tx2 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='get',
            kwargs={},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2 = decode(tx2)

        tx_batch = {
            'transactions': [tx, tx2]
        }

        e = execution.SerialExecutor(executor=self.client.executor)

        results = e.execute_tx_batch(
            driver=self.client.raw_driver,
            batch=tx_batch,
            timestamp=time.time(),
            input_hash='A' * 64,
            stamp_cost=20_000
        )

        td1, td2 = results

        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], 'howdy')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(len(td2['state']), 0)
        self.assertEqual(td2['stamps_used'], 1)

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

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

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

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

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

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'howdy'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx = decode(tx)

        tx2 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='get',
            kwargs={},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2 = decode(tx2)

        tx3 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'something'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx3 = decode(tx3)

        tx4 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'something2'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx4 = decode(tx4)

        tx_batch = {
            'transactions': [tx, tx2, tx3, tx4]
        }

        e = execution.SerialExecutor(executor=self.client.executor)

        results = e.execute_tx_batch(
            driver=self.client.raw_driver,
            batch=tx_batch,
            timestamp=time.time(),
            input_hash='A' * 64,
            stamp_cost=20_000
        )

        td1, td2, td3, td4 = results

        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], 'howdy')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(len(td2['state']), 0)
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(td3['status'], 0)
        self.assertEqual(td3['state'][0]['key'], 'testing.v')
        self.assertEqual(td3['state'][0]['value'], 'something')
        self.assertEqual(td3['stamps_used'], 1)

        self.assertEqual(td4['status'], 0)
        self.assertEqual(td4['state'][0]['key'], 'testing.v')
        self.assertEqual(td4['state'][0]['value'], 'something2')
        self.assertEqual(td4['stamps_used'], 1)

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

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

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

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

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

        self.client.raw_driver.commit()
        self.client.raw_driver.clear_pending_state()

        stu = Wallet()

        tx1_1 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': 'howdy'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx1_1 = decode(tx1_1)

        tx1_2 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='get',
            kwargs={},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx1_2 = decode(tx1_2)

        tx_batch_1 = {
            'transactions': [tx1_1, tx1_2],
            'timestamp': time.time(),
            'input_hash': 'C' * 64
        }

        tx2_1 = transaction.build_transaction(
            wallet=stu,
            contract='testing',
            function='set',
            kwargs={'var': '123'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2_1 = decode(tx2_1)

        jeff = Wallet()
        tx2_2 = transaction.build_transaction(
            wallet=jeff,
            contract='testing',
            function='set',
            kwargs={'var': 'poo'},
            stamps=100_000,
            processor='0' * 64,
            nonce=0
        )

        tx2_2 = decode(tx2_2)

        tx_batch_2 = {
            'transactions': [tx2_1, tx2_2],
            'timestamp': time.time(),
            'input_hash': 'A' * 64
        }

        work = [tx_batch_1, tx_batch_2]

        exe = execution.SerialExecutor(executor=self.client.executor)

        results = exe.execute_work(
            driver=self.client.raw_driver,
            work=work,
            previous_block_hash='B' * 64,
            wallet=Wallet(),
            stamp_cost=20_000
        )

        sb1, sb2 = results

        td1, td2 = sb1['transactions']
        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], 'howdy')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(len(td2['state']), 0)
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(sb1['input_hash'], tx_batch_1['input_hash'])
        self.assertEqual(sb1['subblock'], 0)
        self.assertEqual(sb1['previous'], 'B' * 64)

        td1, td2 = sb2['transactions']
        self.assertEqual(td1['status'], 0)
        self.assertEqual(td1['state'][0]['key'], 'testing.v')
        self.assertEqual(td1['state'][0]['value'], '123')
        self.assertEqual(td1['stamps_used'], 1)

        self.assertEqual(td2['status'], 0)
        self.assertEqual(td2['state'][0]['key'], 'testing.v')
        self.assertEqual(td2['state'][0]['value'], 'poo')
        self.assertEqual(td2['stamps_used'], 1)

        self.assertEqual(sb2['input_hash'], tx_batch_2['input_hash'])
        self.assertEqual(sb2['subblock'], 1)
        self.assertEqual(sb2['previous'], 'B' * 64)

    def test_no_txs_merklizes_and_signs_input_hash(self):
        tx_batch_1 = {
            'transactions': [],
            'timestamp': time.time(),
            'input_hash': 'A' * 64
        }

        work = [tx_batch_1]

        w = Wallet()

        exe = execution.SerialExecutor(executor=self.client.executor)

        results = exe.execute_work(
            driver=self.client.raw_driver,
            work=work,
            previous_block_hash='B' * 64,
            wallet=w,
            stamp_cost=20_000
        )

        self.assertTrue(verify(w.verifying_key, results[0]['input_hash'], results[0]['merkle_tree']['signature']))

        h = hashlib.sha3_256()
        h.update(bytes.fromhex(results[0]['input_hash']))

        self.assertEqual(h.hexdigest(), results[0]['merkle_tree']['leaves'][0])

    def test_acquire_work_1_master_gathers_tx_batches(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.send_work(),
            dl.acquire_work(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        _, _, _, w, _, _ = self.loop.run_until_complete(tasks)

        self.assertEqual(len(w), 1)
        self.assertEqual(w[0]['sender'], mw.verifying_key)

    def test_acquire_work_2_masters_gathers_tx_batches_pads_work_and_waits_if_missing(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()
        mw2 = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key, mw2.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key, mw2.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1],
            mw2.verifying_key: 'tpc://127.0.0.1:18003'
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.send_work(),
            dl.acquire_work(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        _, _, _, w, _, _ = self.loop.run_until_complete(tasks)

        self.assertEqual(len(w), 2)
        self.assertEqual(w[0]['sender'], mw.verifying_key)

        self.assertEqual(w[1]['sender'], mw2.verifying_key)
        self.assertEqual(w[1]['input_hash'], mw2.verifying_key)
        self.assertEqual(w[1]['signature'], '0' * 128)

    def test_process_new_work_processes_tx_batch(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        mnq = router.QueueProcessor()
        mn.router.add_service(base.CONTENDER_SERVICE, mnq)

        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.send_work(),
            dl.process_new_work(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        sbc = mnq.q.pop(0)

        self.assertEqual(len(sbc), 1)
        self.assertEqual(sbc[0]['previous'], '0' * 64)
        self.assertEqual(sbc[0]['signer'], dw.verifying_key)

    def test_masternode_delegate_single_loop_works(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=ContractDriver(driver=InMemDriver())
        )

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.loop(),
            dl.loop(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        # sbc = mnq.q.pop(0)
        #
        # self.assertEqual(len(sbc), 1)
        # self.assertEqual(sbc[0]['previous'], '0' * 64)
        # self.assertEqual(sbc[0]['signer'], dw.verifying_key)

    # def test_masternode_delegate_single_loop_commits_state_changes(self):
    #     ips = [
    #         'tcp://127.0.0.1:18001',
    #         'tcp://127.0.0.1:18002'
    #     ]
    #
    #     dw = Wallet()
    #     mw = Wallet()
    #
    #     self.authenticator.add_verifying_key(mw.verifying_key)
    #     self.authenticator.add_verifying_key(dw.verifying_key)
    #     self.authenticator.configure()
    #
    #     mnd = ContractDriver(driver=InMemDriver())
    #     mn = masternode.Masternode(
    #         socket_base=ips[0],
    #         ctx=self.ctx,
    #         wallet=mw,
    #         constitution={
    #             'masternodes': [mw.verifying_key],
    #             'delegates': [dw.verifying_key]
    #         },
    #         driver=mnd
    #     )
    #     sender = Wallet()
    #     mnd.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)
    #
    #     dld = ContractDriver(driver=InMemDriver())
    #     dld.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)
    #     dl = delegate.Delegate(
    #         socket_base=ips[1],
    #         ctx=self.ctx,
    #         wallet=dw,
    #         constitution={
    #             'masternodes': [mw.verifying_key],
    #             'delegates': [dw.verifying_key]
    #         },
    #         driver=dld
    #     )
    #
    #     tx = transaction.build_transaction(
    #         wallet=sender,
    #         contract='currency',
    #         function='transfer',
    #         kwargs={
    #             'amount': 1338,
    #             'to': 'jeff'
    #         },
    #         stamps=5000,
    #         nonce=0,
    #         processor=mw.verifying_key
    #     )
    #
    #     tx_decoded = decode(tx)
    #     mn.tx_batcher.queue.append(tx_decoded)
    #
    #     peers = {
    #         mw.verifying_key: ips[0],
    #         dw.verifying_key: ips[1]
    #     }
    #
    #     mn.network.peers = peers
    #     dl.network.peers = peers
    #
    #     tasks = asyncio.gather(
    #         mn.router.serve(),
    #         dl.router.serve(),
    #         mn.loop(),
    #         dl.loop(),
    #         stop_server(mn.router, 1),
    #         stop_server(dl.router, 1),
    #     )
    #
    #     self.loop.run_until_complete(tasks)
    #
    #     dbal = dld.get_var(contract='currency', variable='balances', arguments=['jeff'])
    #     mbal = mnd.get_var(contract='currency', variable='balances', arguments=['jeff'])
    #
    #     self.assertEqual(dbal, 1338)
    #     self.assertEqual(mbal, 1338)

    def test_masternode_delegate_single_loop_updates_block_num(self):
        ips = [
            'tcp://127.0.0.1:18001',
            'tcp://127.0.0.1:18002'
        ]

        dw = Wallet()
        mw = Wallet()

        self.authenticator.add_verifying_key(mw.verifying_key)
        self.authenticator.add_verifying_key(dw.verifying_key)
        self.authenticator.configure()

        mnd = ContractDriver(driver=InMemDriver())
        mn = masternode.Masternode(
            socket_base=ips[0],
            ctx=self.ctx,
            wallet=mw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=mnd
        )
        sender = Wallet()
        mnd.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)

        dld = ContractDriver(driver=InMemDriver())
        dld.set_var(contract='currency', variable='balances', arguments=[sender.verifying_key], value=1_000_000)
        dl = delegate.Delegate(
            socket_base=ips[1],
            ctx=self.ctx,
            wallet=dw,
            constitution={
                'masternodes': [mw.verifying_key],
                'delegates': [dw.verifying_key]
            },
            driver=dld
        )

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

        tx_decoded = decode(tx)
        mn.tx_batcher.queue.append(tx_decoded)

        peers = {
            mw.verifying_key: ips[0],
            dw.verifying_key: ips[1]
        }

        mn.network.peers = peers
        dl.network.peers = peers

        tasks = asyncio.gather(
            mn.router.serve(),
            dl.router.serve(),
            mn.loop(),
            dl.loop(),
            stop_server(mn.router, 1),
            stop_server(dl.router, 1),
        )

        self.loop.run_until_complete(tasks)

        dh = storage.get_latest_block_height(dld)
        mh = storage.get_latest_block_height(mnd)

        self.assertEqual(dh, 1)
        self.assertEqual(mh, 1)
示例#14
0
class TestUpdatingState(TestCase):
    def setUp(self):
        self.driver = ContractDriver()
        self.nonces = storage.NonceStorage()
        self.nonces.flush()
        self.driver.flush()
        self.driver.clear_pending_state()

    def tearDown(self):
        self.nonces.flush()
        self.driver.flush()
        self.driver.clear_pending_state()

    def test_state_updated_to_correct_values_in_tx(self):
        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        self.assertIsNone(v1)
        self.assertIsNone(v2)

        storage.update_state_with_transaction(tx=tx_1,
                                              driver=self.driver,
                                              nonces=self.nonces)

        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        self.assertEqual(v1, 'there')
        self.assertEqual(v2, 'jeff')

    def test_nonces_set_to_tx_value(self):
        n = self.nonces.get_latest_nonce(sender='abc', processor='def')
        self.assertEqual(n, 0)

        storage.update_state_with_transaction(tx=tx_1,
                                              driver=self.driver,
                                              nonces=self.nonces)

        n = self.nonces.get_latest_nonce(sender='abc', processor='def')
        self.assertEqual(n, 124)

    def test_nonces_deleted_after_all_updates(self):
        self.nonces.set_pending_nonce(sender='abc', processor='def', value=122)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')

        self.assertEqual(n, 122)

        storage.update_state_with_transaction(tx=tx_1,
                                              driver=self.driver,
                                              nonces=self.nonces)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')

        self.assertEqual(n, None)

    def test_multiple_txs_deletes_multiple_nonces(self):
        self.nonces.set_pending_nonce(sender='abc', processor='def', value=122)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')
        self.assertEqual(n, 122)

        self.nonces.set_pending_nonce(sender='xxx', processor='yyy', value=4)

        n = self.nonces.get_pending_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, 4)

        storage.update_state_with_transaction(tx=tx_1,
                                              driver=self.driver,
                                              nonces=self.nonces)

        storage.update_state_with_transaction(tx=tx_2,
                                              driver=self.driver,
                                              nonces=self.nonces)

        storage.update_state_with_transaction(tx=tx_3,
                                              driver=self.driver,
                                              nonces=self.nonces)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')
        self.assertEqual(n, None)

        n = self.nonces.get_pending_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, None)

        n = self.nonces.get_latest_nonce(sender='abc', processor='def')
        self.assertEqual(n, 125)

        n = self.nonces.get_latest_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, 43)

    def test_multiple_tx_state_updates_correctly(self):
        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        v3 = self.driver.get('name2', mark=False)

        v4 = self.driver.get('another', mark=False)
        v5 = self.driver.get('something', mark=False)

        self.assertIsNone(v1)
        self.assertIsNone(v2)
        self.assertIsNone(v3)
        self.assertIsNone(v4)
        self.assertIsNone(v5)

        storage.update_state_with_transaction(tx=tx_1,
                                              driver=self.driver,
                                              nonces=self.nonces)

        storage.update_state_with_transaction(tx=tx_2,
                                              driver=self.driver,
                                              nonces=self.nonces)

        storage.update_state_with_transaction(tx=tx_3,
                                              driver=self.driver,
                                              nonces=self.nonces)

        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        v3 = self.driver.get('name2', mark=False)

        v4 = self.driver.get('another', mark=False)
        v5 = self.driver.get('something', mark=False)

        self.assertEqual(v1, 'there2')
        self.assertEqual(v2, 'jeff')
        self.assertEqual(v3, 'jeff2')
        self.assertEqual(v4, 'value')
        self.assertEqual(v5, 'else')

    def test_update_with_block_sets_hash_and_height(self):
        _hash = storage.get_latest_block_hash(self.driver)
        num = storage.get_latest_block_height(self.driver)

        self.assertEqual(_hash, '0' * 64)
        self.assertEqual(num, 0)

        storage.update_state_with_block(block=block,
                                        driver=self.driver,
                                        nonces=self.nonces)

        _hash = storage.get_latest_block_hash(self.driver)
        num = storage.get_latest_block_height(self.driver)

        self.assertEqual(_hash, 'f' * 64)
        self.assertEqual(num, 555)

    def test_update_with_block_sets_nonces_correctly(self):
        self.nonces.set_pending_nonce(sender='abc', processor='def', value=122)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')
        self.assertEqual(n, 122)

        self.nonces.set_pending_nonce(sender='xxx', processor='yyy', value=4)

        n = self.nonces.get_pending_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, 4)

        storage.update_state_with_block(block=block,
                                        driver=self.driver,
                                        nonces=self.nonces)

        n = self.nonces.get_pending_nonce(sender='abc', processor='def')
        self.assertEqual(n, None)

        n = self.nonces.get_pending_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, None)

        n = self.nonces.get_latest_nonce(sender='abc', processor='def')
        self.assertEqual(n, 125)

        n = self.nonces.get_latest_nonce(sender='xxx', processor='yyy')
        self.assertEqual(n, 43)

    def test_update_state_with_block_sets_state_correctly(self):
        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        v3 = self.driver.get('name2', mark=False)

        v4 = self.driver.get('another', mark=False)
        v5 = self.driver.get('something', mark=False)

        self.assertIsNone(v1)
        self.assertIsNone(v2)
        self.assertIsNone(v3)
        self.assertIsNone(v4)
        self.assertIsNone(v5)

        storage.update_state_with_block(block=block,
                                        driver=self.driver,
                                        nonces=self.nonces)

        v1 = self.driver.get('hello', mark=False)
        v2 = self.driver.get('name', mark=False)

        v3 = self.driver.get('name2', mark=False)

        v4 = self.driver.get('another', mark=False)
        v5 = self.driver.get('something', mark=False)

        self.assertEqual(v1, 'there2')
        self.assertEqual(v2, 'jeff')
        self.assertEqual(v3, 'jeff2')
        self.assertEqual(v4, 'value')
        self.assertEqual(v5, 'else')
示例#15
0
class TestExecutor(TestCase):
    def setUp(self):
        self.d = ContractDriver()
        self.d.flush()

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

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

        self.compiler = ContractingCompiler()

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

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

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

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

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

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

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

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

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

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

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

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

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

        code = '''v = Variable()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        this_is_a_passed_in_variable = 555

        env = {'this_is_a_passed_in_variable': this_is_a_passed_in_variable}

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

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

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

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

        this_is_a_passed_in_variable = 555

        env = {
            'this_is_another_passed_in_variable': this_is_a_passed_in_variable
        }

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

        self.assertEqual(output['status_code'], 1)
class TestMetering(TestCase):
    def setUp(self):
        # Hard load the submission contract
        self.d = ContractDriver()
        self.d.flush()

        with open(contracting.__path__[0] + '/contracts/submission.s.py') as f:
            contract = f.read()

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

        # Execute the currency contract with metering disabled
        self.e = Executor(driver=self.d)
        self.e.execute(**TEST_SUBMISSION_KWARGS,
                       kwargs=submission_kwargs_for_file(
                           './test_contracts/currency.s.py'),
                       metering=False,
                       auto_commit=True)

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

    def test_simple_execution_deducts_stamps(self):
        prior_balance = self.d.get('currency.balances:stu')

        output = self.e.execute('stu',
                                'currency',
                                'transfer',
                                kwargs={
                                    'amount': 100,
                                    'to': 'colin'
                                },
                                auto_commit=True)

        new_balance = self.d.get('currency.balances:stu')

        self.assertEqual(float(prior_balance - new_balance - 100),
                         output['stamps_used'] / STAMPS_PER_TAU)

    def test_too_few_stamps_fails_and_deducts_properly(self):
        prior_balance = self.d.get('currency.balances:stu')

        print(prior_balance)

        small_amount_of_stamps = 1 * STAMPS_PER_TAU

        output = self.e.execute('stu',
                                'currency',
                                'transfer',
                                kwargs={
                                    'amount': 100,
                                    'to': 'colin'
                                },
                                stamps=small_amount_of_stamps,
                                auto_commit=True)

        print(output)

        new_balance = self.d.get('currency.balances:stu')

        self.assertEqual(float(prior_balance - new_balance),
                         output['stamps_used'] / STAMPS_PER_TAU)

    def test_adding_too_many_stamps_throws_error(self):
        prior_balance = self.d.get('currency.balances:stu')
        too_many_stamps = (prior_balance + 1000) * STAMPS_PER_TAU

        output = self.e.execute('stu',
                                'currency',
                                'transfer',
                                kwargs={
                                    'amount': 100,
                                    'to': 'colin'
                                },
                                stamps=too_many_stamps,
                                auto_commit=True)

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

    def test_adding_all_stamps_with_infinate_loop_eats_all_balance(self):
        self.d.set('currency.balances:stu', 500)
        self.d.commit()

        prior_balance = self.d.get('currency.balances:stu')

        prior_balance *= STAMPS_PER_TAU

        self.e.execute(**TEST_SUBMISSION_KWARGS,
                       kwargs=submission_kwargs_for_file(
                           './test_contracts/inf_loop.s.py'),
                       stamps=prior_balance,
                       metering=True,
                       auto_commit=True)

        new_balance = self.d.get('currency.balances:stu')

        # Not all stamps will be deducted because it will blow up in the middle of execution
        self.assertTrue(new_balance < 0.01)

    def test_submitting_contract_succeeds_with_enough_stamps(self):
        prior_balance = self.d.get('currency.balances:stu')

        print(prior_balance)

        output = self.e.execute(**TEST_SUBMISSION_KWARGS,
                                kwargs=submission_kwargs_for_file(
                                    './test_contracts/erc20_clone.s.py'),
                                auto_commit=True)
        print(output)

        new_balance = self.d.get('currency.balances:stu')

        print(new_balance)

        self.assertEqual(float(prior_balance - new_balance),
                         output['stamps_used'] / STAMPS_PER_TAU)

    def test_pending_writes_has_deducted_stamp_amount_prior_to_auto_commit(
            self):
        prior_balance = self.d.get('currency.balances:stu')

        output = self.e.execute(**TEST_SUBMISSION_KWARGS,
                                kwargs=submission_kwargs_for_file(
                                    './test_contracts/erc20_clone.s.py'),
                                auto_commit=False)
        self.assertNotEquals(
            self.e.driver.pending_writes['currency.balances:stu'],
            prior_balance)
示例#17
0
class TestNode(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        self.blocks = storage.BlockStorage()

        self.driver = ContractDriver(driver=InMemDriver())
        self.b = masternode.BlockService(blocks=self.blocks,
                                         driver=self.driver)

        self.blocks.drop_collections()
        self.driver.flush()

        self.authenticator = authentication.SocketAuthenticator(
            client=ContractingClient(), ctx=self.ctx)

    def tearDown(self):
        self.authenticator.authenticator.stop()
        self.ctx.destroy()
        self.loop.close()
        self.b.blocks.drop_collections()
        self.b.driver.flush()

    def test_catchup(self):
        driver = ContractDriver(driver=InMemDriver())

        dl_vk = Wallet().verifying_key

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_router.add_service(base.BLOCK_SERVICE, self.b)

        nw = Wallet()
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=nw,
                         constitution={
                             'masternodes': [mn_wallet.verifying_key],
                             'delegates': [dl_vk]
                         },
                         driver=driver)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(nw.verifying_key)
        self.authenticator.add_verifying_key(dl_vk)
        self.authenticator.configure()

        blocks = generate_blocks(3)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])
        storage.set_latest_block_height(3, self.driver)

        tasks = asyncio.gather(
            mn_router.serve(),
            node.catchup('tcp://127.0.0.1:18001', mn_wallet.verifying_key),
            stop_server(mn_router, 2))

        self.loop.run_until_complete(tasks)

        self.assertEqual(storage.get_latest_block_height(node.driver), 3)

    def test_catchup_with_nbn_added(self):
        driver = ContractDriver(driver=InMemDriver())

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_router.add_service(base.BLOCK_SERVICE, self.b)

        nw = Wallet()
        dlw = Wallet()
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=nw,
                         constitution={
                             'masternodes': [mn_wallet.verifying_key],
                             'delegates': [dlw.verifying_key]
                         },
                         driver=driver)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(nw.verifying_key)
        self.authenticator.add_verifying_key(dlw.verifying_key)
        self.authenticator.configure()

        blocks = generate_blocks(4)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])

        storage.set_latest_block_height(3, self.driver)

        node.new_block_processor.q.append(blocks[3])

        tasks = asyncio.gather(
            mn_router.serve(),
            node.catchup('tcp://127.0.0.1:18001', mn_wallet.verifying_key),
            stop_server(mn_router, 1))

        self.loop.run_until_complete(tasks)
        self.assertEqual(storage.get_latest_block_height(node.driver), 4)

    def test_should_process_block_false_if_failed_block(self):
        block = {
            'hash': 'f' * 64,
            'number': 1,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_current_height_not_increment(self):
        block = {
            'hash': 'a' * 64,
            'number': 2,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_previous_if_not_current_hash(self):
        block = {
            'hash': 'a' * 64,
            'number': 1,
            'previous': 'b' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_false_if_expected_block_not_equal_to_provided_block(
            self):
        block = {
            'hash': 'a' * 64,
            'number': 1,
            'previous': '0' * 64,
            'subblocks': []
        }

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertFalse(node.should_process(block))

    def test_should_process_block_true_if_expected_block_equal_to_block(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        self.assertTrue(node.should_process(block))

    def test_process_new_block_updates_state(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18002',
                         ctx=self.ctx,
                         wallet=Wallet(),
                         constitution={
                             'masternodes': [Wallet().verifying_key],
                             'delegates': [Wallet().verifying_key]
                         },
                         driver=driver)

        node.process_new_block(block)

        self.assertEqual(storage.get_latest_block_height(node.driver), 1)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         block['hash'])

    def test_process_new_block_stores_block_if_should_store(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        node.process_new_block(block)

        b = node.blocks.get_block(1)

        self.assertEqual(b, block)

    def test_process_new_block_clears_cache(self):
        block = canonical.block_from_subblocks(subblocks=[],
                                               previous_hash='0' * 64,
                                               block_num=1)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        node.driver.cache['test'] = 123

        node.process_new_block(block)

        self.assertIsNone(node.driver.cache.get('test'))

    def test_process_new_block_cleans_nbn(self):
        blocks = generate_blocks(2)

        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(
            socket_base='tcp://127.0.0.1:18002',
            ctx=self.ctx,
            wallet=Wallet(),
            constitution={
                'masternodes': [Wallet().verifying_key],
                'delegates': [Wallet().verifying_key]
            },
            driver=driver,
            store=True,
            blocks=self.blocks,
        )

        # Add one old and one new block.
        # Function should only delete the old one
        node.new_block_processor.q.append(blocks[0])
        node.new_block_processor.q.append(blocks[1])

        node.process_new_block(blocks[0])

        block = node.new_block_processor.q[0]

        self.assertEqual(block, blocks[1])
        self.assertEqual(len(node.new_block_processor.q), 1)

    def test_start_boots_up_normally(self):
        # This MN will also provide 'catch up' services

        mn_bootnode = 'tcp://127.0.0.1:18001'
        mn_wallet = Wallet()
        mn_router = router.Router(socket_id=mn_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=mn_wallet)

        mn_network = network.Network(wallet=mn_wallet,
                                     ip_string=mn_bootnode,
                                     ctx=self.ctx,
                                     router=mn_router)

        blocks = generate_blocks(4)

        self.blocks.store_block(blocks[0])
        self.blocks.store_block(blocks[1])
        self.blocks.store_block(blocks[2])

        storage.set_latest_block_height(3, self.driver)

        mn_router.add_service(
            base.BLOCK_SERVICE,
            masternode.BlockService(self.blocks, self.driver))

        dl_bootnode = 'tcp://127.0.0.1:18002'
        dl_wallet = Wallet()
        dl_router = router.Router(socket_id=dl_bootnode,
                                  ctx=self.ctx,
                                  secure=True,
                                  wallet=dl_wallet)
        dl_network = network.Network(wallet=dl_wallet,
                                     ip_string=dl_bootnode,
                                     ctx=self.ctx,
                                     router=dl_router)

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        self.authenticator.add_verifying_key(mn_wallet.verifying_key)
        self.authenticator.add_verifying_key(dl_wallet.verifying_key)
        self.authenticator.add_verifying_key(node_w.verifying_key)

        self.authenticator.configure()

        vks = [mn_wallet.verifying_key, dl_wallet.verifying_key]

        tasks = asyncio.gather(
            mn_router.serve(),
            dl_router.serve(),
            mn_network.start(bootnodes, vks),
            dl_network.start(bootnodes, vks),
            stop_server(mn_router, 0.2),
            stop_server(dl_router, 0.2),
        )

        self.loop.run_until_complete(tasks)

        tasks = asyncio.gather(mn_router.serve(), dl_router.serve(),
                               node.start(), stop_server(mn_router, 1),
                               stop_server(dl_router, 1),
                               stop_server(node.router, 1))

        self.loop.run_until_complete(tasks)

        self.assertEqual(storage.get_latest_block_height(node.driver), 3)
        self.assertEqual(storage.get_latest_block_hash(node.driver),
                         blocks[2]['hash'])

    def test_new_block_service_appends_to_q_to_process_msg(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        self.loop.run_until_complete(nb.process_message(msg))

        self.assertEqual(nb.q, [msg])

    def test_wait_for_next_holds_until_q_len_greater_than_0(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        async def slow_add():
            await asyncio.sleep(0.5)
            await nb.process_message(msg)

        self.loop.run_until_complete(slow_add())

        self.assertEqual(nb.q, [msg])

    def test_wait_for_next_pops_first_in_q(self):
        nb = base.NewBlock(driver=ContractDriver())

        msg = 'test'

        nb.q.append('first')

        tasks = asyncio.gather(nb.process_message(msg), nb.wait_for_next_nbn())

        _, r = self.loop.run_until_complete(tasks)

        self.assertEqual(r, 'first')

    def test_wait_for_next_clears_q(self):
        nb = base.NewBlock(driver=ContractDriver())

        nb.q.append('first')
        nb.q.append('second')
        nb.q.append('third')

        tasks = asyncio.gather(nb.wait_for_next_nbn())

        self.loop.run_until_complete(tasks)

        self.assertEqual(nb.q, [])

    def test_get_member_peers_returns_vk_ip_pairs(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        m = node._get_member_peers('masternodes')
        d = node._get_member_peers('delegates')

        self.assertEqual(m, {mn_wallet.verifying_key: mn_bootnode})
        self.assertEqual(d, {dl_wallet.verifying_key: dl_bootnode})

    def test_get_delegate_peers_returns_deletates(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        d = node.get_delegate_peers()

        self.assertEqual(d, {dl_wallet.verifying_key: dl_bootnode})

    def test_get_masternode_peers_gets_masternodes(self):
        mn_wallet = Wallet()
        dl_wallet = Wallet()

        mn_bootnode = 'tcp://127.0.0.1:18001'
        dl_bootnode = 'tcp://127.0.0.1:18002'

        constitution = {
            'masternodes': [mn_wallet.verifying_key],
            'delegates': [dl_wallet.verifying_key]
        }

        bootnodes = {
            mn_wallet.verifying_key: mn_bootnode,
            dl_wallet.verifying_key: dl_bootnode
        }

        node_w = Wallet()
        driver = ContractDriver(driver=InMemDriver())
        node = base.Node(socket_base='tcp://127.0.0.1:18003',
                         ctx=self.ctx,
                         wallet=node_w,
                         constitution=constitution,
                         driver=driver,
                         store=False,
                         bootnodes=bootnodes)

        # Assume caught up state
        node.network.peers = bootnodes

        m = node.get_masternode_peers()

        self.assertEqual(m, {mn_wallet.verifying_key: mn_bootnode})