def test_many_miners_connect_ready_disconnect(self, qty=5):
        transport = Mock()
        connections = []
        for idx in range(qty):
            conn = StratumProtocol(self.manager)
            conn.connection_made(transport=transport)
            self.assertEqual(idx + 1, len(self.manager.connections))
            self.assertEqual(0, len(self.manager.miners))
            connections.append(conn)

        self.assertEqual(qty, len(self.manager.connections))
        self.assertEqual(0, len(self.manager.miners))

        for idx, conn in enumerate(connections):
            conn.method_subscribe(params=None, msgid=None)
            conn.method_authorize(params=None, msgid=None)
            self.assertEqual(idx + 1, len(self.manager.miners))

        self.assertEqual(qty, len(self.manager.connections))
        self.assertEqual(qty, len(self.manager.miners))
        self.manager.status()

        for idx, conn in enumerate(connections):
            conn.connection_lost(exc=None)
            self.assertEqual(qty - idx - 1, len(self.manager.connections))
            self.assertEqual(qty - idx - 1, len(self.manager.miners))

        self.assertEqual(0, len(self.manager.connections))
        self.assertEqual(0, len(self.manager.miners))
 def test_miner_connect_disconnect(self):
     conn = StratumProtocol(self.manager)
     conn.connection_made(transport=None)
     self.assertEqual(1, len(self.manager.connections))
     self.assertEqual(0, len(self.manager.miners))
     conn.connection_lost(exc=None)
     self.assertEqual(0, len(self.manager.connections))
     self.assertEqual(0, len(self.manager.miners))
    def test_miner_invalid_address(self):
        conn = StratumProtocol(self.manager)
        conn.send_error = MagicMock(return_value=None)

        transport = Mock()
        conn.connection_made(transport=transport)

        params = {'address': 'X'}
        conn.method_subscribe(params=params, msgid=None)
        conn.send_error.assert_called_once_with(None, conn.INVALID_ADDRESS)
    def test_miner_some_jsonrpc_methods(self):
        conn = StratumProtocol(self.manager)
        conn.connection_made(transport=None)

        conn.send_result = MagicMock(return_value=None)
        conn.method_extranonce_subscribe(params=None, msgid=None)
        conn.send_result.assert_called_with(None, True)

        conn.send_result = MagicMock(return_value=None)
        conn.method_multi_version(params=None, msgid=None)
        conn.send_result.assert_called_with(None, True)
    def test_miner_method_subscribe_valid_address(self):
        conn = StratumProtocol(self.manager)
        transport = Mock()
        conn.connection_made(transport=transport)
        conn.send_error = MagicMock(return_value=None)

        params = {
            'address': 'HVZjvL1FJ23kH3buGNuttVRsRKq66WHUVZ'
        }
        conn.method_subscribe(params=params, msgid=None)
        conn.send_error.assert_not_called()
        transport.close.assert_not_called()
    def test_miner_method_subscribe_invalid_address2(self):
        conn = StratumProtocol(self.manager)
        transport = Mock()
        conn.connection_made(transport=transport)
        conn.send_error = MagicMock(return_value=None)

        params = {
            'address': 'ZiCa'
        }
        conn.method_subscribe(params=params, msgid=None)
        conn.send_error.assert_called_once()
        transport.close.assert_called_once()
    def _get_ready_miner(self, address: Optional[str] = None) -> StratumProtocol:
        conn = StratumProtocol(self.manager)
        conn._update_job_timestamp = False

        transport = Mock()
        conn.connection_made(transport=transport)

        if address:
            params = {'address': address}
        else:
            params = {}
        conn.method_subscribe(params=params, msgid=None)
        conn.method_authorize(params=None, msgid=None)
        return conn
    def test_miner_connect_ready_disconnect(self):
        conn = StratumProtocol(self.manager)
        transport = Mock()
        conn.connection_made(transport=transport)
        self.assertEqual(1, len(self.manager.connections))
        self.assertEqual(0, len(self.manager.miners))

        conn.method_subscribe(params=None, msgid=None)
        conn.method_authorize(params=None, msgid=None)
        self.assertEqual(1, len(self.manager.miners))

        conn.connection_lost(exc=None)
        self.assertEqual(0, len(self.manager.connections))
        self.assertEqual(0, len(self.manager.miners))
class DifficultyTestCase(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        manager = MagicMock()
        transport = MagicMock()
        self.protocol = StratumProtocol(manager)
        self.protocol.connection_made(transport)
        self.protocol.current_job = MinerBlockJob(BLOCK_DATA_1, 0)

    def test_estimator_no_job(self):
        self.protocol.current_job = None
        self.loop.run_until_complete(self.protocol.estimator_loop())

    def test_estimator_empty(self):
        self.loop.run_until_complete(self.protocol.estimator_loop())

    def test_estimator_one_work(self):
        now = time.time()
        self.protocol._submitted_work.append(SubmittedWork(now, 25.0, 8))
        self.loop.run_until_complete(self.protocol.estimator_loop())

    def test_estimator_fixed_weight(self):
        now = time.time()
        hashpower = 2**40
        for _ in range(200):
            weight = self.protocol.current_weight
            geometric_p = 2**(-weight)
            trials = numpy.random.geometric(geometric_p)
            dt = 1.0 * trials / hashpower
            self.protocol._submitted_work.append(
                SubmittedWork(now + dt, weight, dt))
            self.loop.run_until_complete(self.protocol.estimator_loop())
            print('!! hashrate_ghs:', self.protocol.hashrate_ghs)
            now += dt