class TestPeers(TestCase):
    def setUp(self):
        self.wallet = Wallet()

        # Wallets for VKs
        self.test_wallet_1 = Wallet()
        self.test_wallet_2 = Wallet()

        self.peer_table = {
            self.test_wallet_1.verifying_key().hex(): 'ipc:///tmp/n1',
            self.test_wallet_2.verifying_key().hex(): 'ipc:///tmp/n2',
        }

        self.ctx = zmq.asyncio.Context()
        self.loop = asyncio.new_event_loop()

        self.contacts = MockContacts(
            masters=[self.test_wallet_1.verifying_key().hex()],
            delegates=[self.test_wallet_2.verifying_key().hex()])

        self.paramaters = Parameters(socket_base='tcp://127.0.0.1',
                                     wallet=self.wallet,
                                     ctx=self.ctx,
                                     contacts=self.contacts)

        self.authenticator = SocketAuthenticator(wallet=self.wallet,
                                                 contacts=self.contacts,
                                                 ctx=self.ctx)

        asyncio.set_event_loop(self.loop)

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

    def testInit(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=DEL,
                  service_type=ServiceType.INCOMING_WORK)

    def test_connect_test_wallet(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=DEL,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        p.connect(SocketStruct.from_string('ipc:///tmp/n1'),
                  self.test_wallet_1.verifying_key().hex())

        socket = p.sockets.get(self.test_wallet_1.verifying_key().hex())

        self.assertIsNotNone(socket)

    def test_connect_twice_doesnt_modify_socket_object(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=DEL,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        p.connect(SocketStruct.from_string('ipc:///tmp/n1'),
                  self.test_wallet_1.verifying_key().hex())

        socket = p.sockets.get(self.test_wallet_1.verifying_key().hex())

        self.assertIsNotNone(socket)

        p.connect(SocketStruct.from_string('ipc:///tmp/n1'),
                  self.test_wallet_1.verifying_key().hex())

        socket2 = p.sockets.get(self.test_wallet_1.verifying_key().hex())

        self.assertEqual(socket, socket2)

    def test_sync_adds_two_sockets_from_network_peer_table(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=ALL,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(self.test_wallet_1.verifying_key().hex())
        socket_2 = p.sockets.get(self.test_wallet_2.verifying_key().hex())

        self.assertIsNotNone(socket_1)
        self.assertIsNotNone(socket_2)

    def test_sync_adds_del_if_peers_del(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=DEL,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_2 = p.sockets.get(self.test_wallet_2.verifying_key().hex())

        self.assertIsNotNone(socket_2)

    def test_sync_adds_del_if_peers_mn(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=MN,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(self.test_wallet_1.verifying_key().hex())

        self.assertIsNotNone(socket_1)

    def test_resync_adds_new_contacts(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=MN,
                  service_type=ServiceType.INCOMING_WORK)

        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(self.test_wallet_1.verifying_key().hex())

        self.assertIsNotNone(socket_1)

        new_wallet = Wallet()

        p1.peer_service.table[
            new_wallet.verifying_key().hex()] = 'ipc:///tmp/n3'
        self.contacts.masternodes.append(new_wallet.verifying_key().hex())
        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(new_wallet.verifying_key().hex())
        self.assertIsNotNone(socket_1)

    def test_resync_removes_old_contact(self):
        p1 = Network(wallet=self.wallet,
                     ctx=self.ctx,
                     socket_base='tcp://127.0.0.1')

        p1.peer_service.table = self.peer_table

        new_wallet = Wallet()

        p1.peer_service.table[
            new_wallet.verifying_key().hex()] = 'ipc:///tmp/n3'
        self.contacts.masternodes.append(new_wallet.verifying_key().hex())
        self.authenticator.sync_certs()

        p = Peers(wallet=self.wallet,
                  ctx=self.ctx,
                  parameters=self.paramaters,
                  node_type=MN,
                  service_type=ServiceType.INCOMING_WORK)

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(new_wallet.verifying_key().hex())
        self.assertIsNotNone(socket_1)

        del p1.peer_service.table[new_wallet.verifying_key().hex()]
        self.contacts.masternodes.remove(new_wallet.verifying_key().hex())

        self.authenticator.sync_certs()

        async def late_refresh():
            await asyncio.sleep(0.3)
            await self.paramaters.refresh()
            p.sync_sockets()

        async def stop():
            await asyncio.sleep(0.5)
            p1.stop()

        tasks = asyncio.gather(p1.start(discover=False), late_refresh(),
                               stop())

        self.loop.run_until_complete(tasks)

        socket_1 = p.sockets.get(new_wallet.verifying_key().hex())
        self.assertIsNone(socket_1)
Ejemplo n.º 2
0
class TestAuthenticator(TestCase):
    def setUp(self):
        self.ctx = zmq.asyncio.Context()
        self.w = Wallet()

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

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

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

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

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

        self.c.flush()

    def test_double_init(self):
        w = Wallet()

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

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

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

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

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

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

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

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

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

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

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

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

        self.assertTrue(
            os.path.exists(
                os.path.join(self.s.cert_dir, f'{fake_od_m.hex()}.key')))
        self.assertTrue(
            os.path.exists(
                os.path.join(self.s.cert_dir, f'{fake_od_d.hex()}.key')))